xref: /freebsd/contrib/less/optfunc.c (revision b2ea244070ff84eab79e04befb7aa30c982fc84d)
1a5f0fb15SPaul Saab /*
2f6b74a7dSXin LI  * Copyright (C) 1984-2017  Mark Nudelman
3a5f0fb15SPaul Saab  *
4a5f0fb15SPaul Saab  * You may distribute under the terms of either the GNU General Public
5a5f0fb15SPaul Saab  * License or the Less License, as specified in the README file.
6a5f0fb15SPaul Saab  *
796e55cc7SXin LI  * For more information, see the README file.
8a5f0fb15SPaul Saab  */
9a5f0fb15SPaul Saab 
10a5f0fb15SPaul Saab 
11a5f0fb15SPaul Saab /*
12a5f0fb15SPaul Saab  * Handling functions for command line options.
13a5f0fb15SPaul Saab  *
14a5f0fb15SPaul Saab  * Most options are handled by the generic code in option.c.
15a5f0fb15SPaul Saab  * But all string options, and a few non-string options, require
16a5f0fb15SPaul Saab  * special handling specific to the particular option.
17a5f0fb15SPaul Saab  * This special processing is done by the "handling functions" in this file.
18a5f0fb15SPaul Saab  *
19a5f0fb15SPaul Saab  * Each handling function is passed a "type" and, if it is a string
20a5f0fb15SPaul Saab  * option, the string which should be "assigned" to the option.
21a5f0fb15SPaul Saab  * The type may be one of:
22a5f0fb15SPaul Saab  *	INIT	The option is being initialized from the command line.
23a5f0fb15SPaul Saab  *	TOGGLE	The option is being changed from within the program.
24a5f0fb15SPaul Saab  *	QUERY	The setting of the option is merely being queried.
25a5f0fb15SPaul Saab  */
26a5f0fb15SPaul Saab 
27a5f0fb15SPaul Saab #include "less.h"
28a5f0fb15SPaul Saab #include "option.h"
29a5f0fb15SPaul Saab 
30a5f0fb15SPaul Saab extern int nbufs;
31000ba3e8STim J. Robbins extern int bufspace;
32a5f0fb15SPaul Saab extern int pr_type;
33a5f0fb15SPaul Saab extern int plusoption;
34a5f0fb15SPaul Saab extern int swindow;
35f0be0a1fSXin LI extern int sc_width;
36a5f0fb15SPaul Saab extern int sc_height;
37a5f0fb15SPaul Saab extern int secure;
38a5f0fb15SPaul Saab extern int dohelp;
39a5f0fb15SPaul Saab extern int any_display;
40a5f0fb15SPaul Saab extern char openquote;
41a5f0fb15SPaul Saab extern char closequote;
42a5f0fb15SPaul Saab extern char *prproto[];
43a5f0fb15SPaul Saab extern char *eqproto;
44a5f0fb15SPaul Saab extern char *hproto;
45c9346414SPaul Saab extern char *wproto;
46a15691bfSXin LI extern char *every_first_cmd;
47a5f0fb15SPaul Saab extern IFILE curr_ifile;
48a5f0fb15SPaul Saab extern char version[];
49efd72c2eSXin LI extern int jump_sline;
50f6b74a7dSXin LI extern long jump_sline_fraction;
51f0be0a1fSXin LI extern int shift_count;
52f6b74a7dSXin LI extern long shift_count_fraction;
53*b2ea2440SXin LI extern LWCHAR rscroll_char;
54*b2ea2440SXin LI extern int rscroll_attr;
55efd72c2eSXin LI extern int less_is_more;
56a5f0fb15SPaul Saab #if LOGFILE
57a5f0fb15SPaul Saab extern char *namelogfile;
58a5f0fb15SPaul Saab extern int force_logfile;
59a5f0fb15SPaul Saab extern int logfile;
60a5f0fb15SPaul Saab #endif
61a5f0fb15SPaul Saab #if TAGS
62a5f0fb15SPaul Saab public char *tagoption = NULL;
63a5f0fb15SPaul Saab extern char *tags;
64a15691bfSXin LI extern char ztags[];
65a5f0fb15SPaul Saab #endif
66a5f0fb15SPaul Saab #if MSDOS_COMPILER
67a5f0fb15SPaul Saab extern int nm_fg_color, nm_bg_color;
68a5f0fb15SPaul Saab extern int bo_fg_color, bo_bg_color;
69a5f0fb15SPaul Saab extern int ul_fg_color, ul_bg_color;
70a5f0fb15SPaul Saab extern int so_fg_color, so_bg_color;
71a5f0fb15SPaul Saab extern int bl_fg_color, bl_bg_color;
72f6b74a7dSXin LI extern int sgr_mode;
73*b2ea2440SXin LI #if MSDOS_COMPILER==WIN32C
74*b2ea2440SXin LI #ifndef COMMON_LVB_UNDERSCORE
75*b2ea2440SXin LI #define COMMON_LVB_UNDERSCORE 0x8000
76*b2ea2440SXin LI #endif
77*b2ea2440SXin LI #endif
78a5f0fb15SPaul Saab #endif
79a5f0fb15SPaul Saab 
80a5f0fb15SPaul Saab 
81a5f0fb15SPaul Saab #if LOGFILE
82a5f0fb15SPaul Saab /*
83a5f0fb15SPaul Saab  * Handler for -o option.
84a5f0fb15SPaul Saab  */
85a5f0fb15SPaul Saab 	public void
86f6b74a7dSXin LI opt_o(type, s)
87f6b74a7dSXin LI 	int type;
88f6b74a7dSXin LI 	char *s;
89a5f0fb15SPaul Saab {
90a5f0fb15SPaul Saab 	PARG parg;
91*b2ea2440SXin LI 	char *filename;
92a5f0fb15SPaul Saab 
93a5f0fb15SPaul Saab 	if (secure)
94a5f0fb15SPaul Saab 	{
95a5f0fb15SPaul Saab 		error("log file support is not available", NULL_PARG);
96a5f0fb15SPaul Saab 		return;
97a5f0fb15SPaul Saab 	}
98a5f0fb15SPaul Saab 	switch (type)
99a5f0fb15SPaul Saab 	{
100a5f0fb15SPaul Saab 	case INIT:
101a15691bfSXin LI 		namelogfile = save(s);
102a5f0fb15SPaul Saab 		break;
103a5f0fb15SPaul Saab 	case TOGGLE:
104a5f0fb15SPaul Saab 		if (ch_getflags() & CH_CANSEEK)
105a5f0fb15SPaul Saab 		{
106a5f0fb15SPaul Saab 			error("Input is not a pipe", NULL_PARG);
107a5f0fb15SPaul Saab 			return;
108a5f0fb15SPaul Saab 		}
109a5f0fb15SPaul Saab 		if (logfile >= 0)
110a5f0fb15SPaul Saab 		{
111a5f0fb15SPaul Saab 			error("Log file is already in use", NULL_PARG);
112a5f0fb15SPaul Saab 			return;
113a5f0fb15SPaul Saab 		}
114a5f0fb15SPaul Saab 		s = skipsp(s);
115a15691bfSXin LI 		if (namelogfile != NULL)
116a15691bfSXin LI 			free(namelogfile);
117*b2ea2440SXin LI 		filename = lglob(s);
118*b2ea2440SXin LI 		namelogfile = shell_unquote(filename);
119*b2ea2440SXin LI 		free(filename);
120a5f0fb15SPaul Saab 		use_logfile(namelogfile);
121a5f0fb15SPaul Saab 		sync_logfile();
122a5f0fb15SPaul Saab 		break;
123a5f0fb15SPaul Saab 	case QUERY:
124a5f0fb15SPaul Saab 		if (logfile < 0)
125a5f0fb15SPaul Saab 			error("No log file", NULL_PARG);
126a5f0fb15SPaul Saab 		else
127a5f0fb15SPaul Saab 		{
128000ba3e8STim J. Robbins 			parg.p_string = namelogfile;
129a5f0fb15SPaul Saab 			error("Log file \"%s\"", &parg);
130a5f0fb15SPaul Saab 		}
131a5f0fb15SPaul Saab 		break;
132a5f0fb15SPaul Saab 	}
133a5f0fb15SPaul Saab }
134a5f0fb15SPaul Saab 
135a5f0fb15SPaul Saab /*
136a5f0fb15SPaul Saab  * Handler for -O option.
137a5f0fb15SPaul Saab  */
138a5f0fb15SPaul Saab 	public void
139f6b74a7dSXin LI opt__O(type, s)
140f6b74a7dSXin LI 	int type;
141f6b74a7dSXin LI 	char *s;
142a5f0fb15SPaul Saab {
143a5f0fb15SPaul Saab 	force_logfile = TRUE;
144a5f0fb15SPaul Saab 	opt_o(type, s);
145a5f0fb15SPaul Saab }
146a5f0fb15SPaul Saab #endif
147a5f0fb15SPaul Saab 
148a5f0fb15SPaul Saab /*
1497f074f9cSXin LI  * Handlers for -j option.
1507f074f9cSXin LI  */
1517f074f9cSXin LI 	public void
152f6b74a7dSXin LI opt_j(type, s)
153f6b74a7dSXin LI 	int type;
154f6b74a7dSXin LI 	char *s;
1557f074f9cSXin LI {
1567f074f9cSXin LI 	PARG parg;
1577f074f9cSXin LI 	char buf[16];
1587f074f9cSXin LI 	int len;
1597f074f9cSXin LI 	int err;
1607f074f9cSXin LI 
1617f074f9cSXin LI 	switch (type)
1627f074f9cSXin LI 	{
1637f074f9cSXin LI 	case INIT:
1647f074f9cSXin LI 	case TOGGLE:
1657f074f9cSXin LI 		if (*s == '.')
1667f074f9cSXin LI 		{
1677f074f9cSXin LI 			s++;
1687f074f9cSXin LI 			jump_sline_fraction = getfraction(&s, "j", &err);
1697f074f9cSXin LI 			if (err)
1707f074f9cSXin LI 				error("Invalid line fraction", NULL_PARG);
1717f074f9cSXin LI 			else
1727f074f9cSXin LI 				calc_jump_sline();
1737f074f9cSXin LI 		} else
1747f074f9cSXin LI 		{
1757f074f9cSXin LI 			int sline = getnum(&s, "j", &err);
1767f074f9cSXin LI 			if (err)
1777f074f9cSXin LI 				error("Invalid line number", NULL_PARG);
1787f074f9cSXin LI 			else
1797f074f9cSXin LI 			{
1807f074f9cSXin LI 				jump_sline = sline;
1817f074f9cSXin LI 				jump_sline_fraction = -1;
1827f074f9cSXin LI 			}
1837f074f9cSXin LI 		}
1847f074f9cSXin LI 		break;
1857f074f9cSXin LI 	case QUERY:
1867f074f9cSXin LI 		if (jump_sline_fraction < 0)
1877f074f9cSXin LI 		{
1887f074f9cSXin LI 			parg.p_int =  jump_sline;
1897f074f9cSXin LI 			error("Position target at screen line %d", &parg);
1907f074f9cSXin LI 		} else
1917f074f9cSXin LI 		{
1927f074f9cSXin LI 
193f6b74a7dSXin LI 			sprintf(buf, ".%06ld", jump_sline_fraction);
194a15691bfSXin LI 			len = (int) strlen(buf);
1957f074f9cSXin LI 			while (len > 2 && buf[len-1] == '0')
1967f074f9cSXin LI 				len--;
1977f074f9cSXin LI 			buf[len] = '\0';
1987f074f9cSXin LI 			parg.p_string = buf;
1997f074f9cSXin LI 			error("Position target at screen position %s", &parg);
2007f074f9cSXin LI 		}
2017f074f9cSXin LI 		break;
2027f074f9cSXin LI 	}
2037f074f9cSXin LI }
2047f074f9cSXin LI 
2057f074f9cSXin LI 	public void
206f6b74a7dSXin LI calc_jump_sline()
2077f074f9cSXin LI {
2087f074f9cSXin LI 	if (jump_sline_fraction < 0)
2097f074f9cSXin LI 		return;
2107f074f9cSXin LI 	jump_sline = sc_height * jump_sline_fraction / NUM_FRAC_DENOM;
2117f074f9cSXin LI }
2127f074f9cSXin LI 
213f0be0a1fSXin LI /*
214f0be0a1fSXin LI  * Handlers for -# option.
215f0be0a1fSXin LI  */
216f0be0a1fSXin LI 	public void
217f6b74a7dSXin LI opt_shift(type, s)
218f6b74a7dSXin LI 	int type;
219f6b74a7dSXin LI 	char *s;
220f0be0a1fSXin LI {
221f0be0a1fSXin LI 	PARG parg;
222f0be0a1fSXin LI 	char buf[16];
223f0be0a1fSXin LI 	int len;
224f0be0a1fSXin LI 	int err;
225f0be0a1fSXin LI 
226f0be0a1fSXin LI 	switch (type)
227f0be0a1fSXin LI 	{
228f0be0a1fSXin LI 	case INIT:
229f0be0a1fSXin LI 	case TOGGLE:
230f0be0a1fSXin LI 		if (*s == '.')
231f0be0a1fSXin LI 		{
232f0be0a1fSXin LI 			s++;
233f0be0a1fSXin LI 			shift_count_fraction = getfraction(&s, "#", &err);
234f0be0a1fSXin LI 			if (err)
235f0be0a1fSXin LI 				error("Invalid column fraction", NULL_PARG);
236f0be0a1fSXin LI 			else
237f0be0a1fSXin LI 				calc_shift_count();
238f0be0a1fSXin LI 		} else
239f0be0a1fSXin LI 		{
240f0be0a1fSXin LI 			int hs = getnum(&s, "#", &err);
241f0be0a1fSXin LI 			if (err)
242f0be0a1fSXin LI 				error("Invalid column number", NULL_PARG);
243f0be0a1fSXin LI 			else
244f0be0a1fSXin LI 			{
245f0be0a1fSXin LI 				shift_count = hs;
246f0be0a1fSXin LI 				shift_count_fraction = -1;
247f0be0a1fSXin LI 			}
248f0be0a1fSXin LI 		}
249f0be0a1fSXin LI 		break;
250f0be0a1fSXin LI 	case QUERY:
251f0be0a1fSXin LI 		if (shift_count_fraction < 0)
252f0be0a1fSXin LI 		{
253f0be0a1fSXin LI 			parg.p_int = shift_count;
254f0be0a1fSXin LI 			error("Horizontal shift %d columns", &parg);
255f0be0a1fSXin LI 		} else
256f0be0a1fSXin LI 		{
257f0be0a1fSXin LI 
258f6b74a7dSXin LI 			sprintf(buf, ".%06ld", shift_count_fraction);
259a15691bfSXin LI 			len = (int) strlen(buf);
260f0be0a1fSXin LI 			while (len > 2 && buf[len-1] == '0')
261f0be0a1fSXin LI 				len--;
262f0be0a1fSXin LI 			buf[len] = '\0';
263f0be0a1fSXin LI 			parg.p_string = buf;
264f0be0a1fSXin LI 			error("Horizontal shift %s of screen width", &parg);
265f0be0a1fSXin LI 		}
266f0be0a1fSXin LI 		break;
267f0be0a1fSXin LI 	}
268f0be0a1fSXin LI }
269f0be0a1fSXin LI 	public void
270f6b74a7dSXin LI calc_shift_count()
271f0be0a1fSXin LI {
272f0be0a1fSXin LI 	if (shift_count_fraction < 0)
273f0be0a1fSXin LI 		return;
274f0be0a1fSXin LI 	shift_count = sc_width * shift_count_fraction / NUM_FRAC_DENOM;
275f0be0a1fSXin LI }
276f0be0a1fSXin LI 
277a5f0fb15SPaul Saab #if USERFILE
278a5f0fb15SPaul Saab 	public void
279f6b74a7dSXin LI opt_k(type, s)
280f6b74a7dSXin LI 	int type;
281f6b74a7dSXin LI 	char *s;
282a5f0fb15SPaul Saab {
283a5f0fb15SPaul Saab 	PARG parg;
284a5f0fb15SPaul Saab 
285a5f0fb15SPaul Saab 	switch (type)
286a5f0fb15SPaul Saab 	{
287a5f0fb15SPaul Saab 	case INIT:
288a5f0fb15SPaul Saab 		if (lesskey(s, 0))
289a5f0fb15SPaul Saab 		{
290000ba3e8STim J. Robbins 			parg.p_string = s;
291a5f0fb15SPaul Saab 			error("Cannot use lesskey file \"%s\"", &parg);
292a5f0fb15SPaul Saab 		}
293a5f0fb15SPaul Saab 		break;
294a5f0fb15SPaul Saab 	}
295a5f0fb15SPaul Saab }
296a5f0fb15SPaul Saab #endif
297a5f0fb15SPaul Saab 
298a5f0fb15SPaul Saab #if TAGS
299a5f0fb15SPaul Saab /*
300a5f0fb15SPaul Saab  * Handler for -t option.
301a5f0fb15SPaul Saab  */
302a5f0fb15SPaul Saab 	public void
303f6b74a7dSXin LI opt_t(type, s)
304f6b74a7dSXin LI 	int type;
305f6b74a7dSXin LI 	char *s;
306a5f0fb15SPaul Saab {
307a5f0fb15SPaul Saab 	IFILE save_ifile;
308a5f0fb15SPaul Saab 	POSITION pos;
309a5f0fb15SPaul Saab 
310a5f0fb15SPaul Saab 	switch (type)
311a5f0fb15SPaul Saab 	{
312a5f0fb15SPaul Saab 	case INIT:
313a15691bfSXin LI 		tagoption = save(s);
314a5f0fb15SPaul Saab 		/* Do the rest in main() */
315a5f0fb15SPaul Saab 		break;
316a5f0fb15SPaul Saab 	case TOGGLE:
317a5f0fb15SPaul Saab 		if (secure)
318a5f0fb15SPaul Saab 		{
319a5f0fb15SPaul Saab 			error("tags support is not available", NULL_PARG);
320a5f0fb15SPaul Saab 			break;
321a5f0fb15SPaul Saab 		}
322a5f0fb15SPaul Saab 		findtag(skipsp(s));
323a5f0fb15SPaul Saab 		save_ifile = save_curr_ifile();
3246dcb072bSXin LI 		/*
3256dcb072bSXin LI 		 * Try to open the file containing the tag
3266dcb072bSXin LI 		 * and search for the tag in that file.
3276dcb072bSXin LI 		 */
3286dcb072bSXin LI 		if (edit_tagfile() || (pos = tagsearch()) == NULL_POSITION)
329a5f0fb15SPaul Saab 		{
3306dcb072bSXin LI 			/* Failed: reopen the old file. */
331a5f0fb15SPaul Saab 			reedit_ifile(save_ifile);
332a5f0fb15SPaul Saab 			break;
333a5f0fb15SPaul Saab 		}
334a5f0fb15SPaul Saab 		unsave_ifile(save_ifile);
335a5f0fb15SPaul Saab 		jump_loc(pos, jump_sline);
336a5f0fb15SPaul Saab 		break;
337a5f0fb15SPaul Saab 	}
338a5f0fb15SPaul Saab }
339a5f0fb15SPaul Saab 
340a5f0fb15SPaul Saab /*
341a5f0fb15SPaul Saab  * Handler for -T option.
342a5f0fb15SPaul Saab  */
343a5f0fb15SPaul Saab 	public void
344f6b74a7dSXin LI opt__T(type, s)
345f6b74a7dSXin LI 	int type;
346f6b74a7dSXin LI 	char *s;
347a5f0fb15SPaul Saab {
348a5f0fb15SPaul Saab 	PARG parg;
349*b2ea2440SXin LI 	char *filename;
350a5f0fb15SPaul Saab 
351a5f0fb15SPaul Saab 	switch (type)
352a5f0fb15SPaul Saab 	{
353a5f0fb15SPaul Saab 	case INIT:
354a15691bfSXin LI 		tags = save(s);
355a5f0fb15SPaul Saab 		break;
356a5f0fb15SPaul Saab 	case TOGGLE:
357a5f0fb15SPaul Saab 		s = skipsp(s);
358a15691bfSXin LI 		if (tags != NULL && tags != ztags)
359a15691bfSXin LI 			free(tags);
360*b2ea2440SXin LI 		filename = lglob(s);
361*b2ea2440SXin LI 		tags = shell_unquote(filename);
362*b2ea2440SXin LI 		free(filename);
363a5f0fb15SPaul Saab 		break;
364a5f0fb15SPaul Saab 	case QUERY:
365000ba3e8STim J. Robbins 		parg.p_string = tags;
366a5f0fb15SPaul Saab 		error("Tags file \"%s\"", &parg);
367a5f0fb15SPaul Saab 		break;
368a5f0fb15SPaul Saab 	}
369a5f0fb15SPaul Saab }
370a5f0fb15SPaul Saab #endif
371a5f0fb15SPaul Saab 
372a5f0fb15SPaul Saab /*
373a5f0fb15SPaul Saab  * Handler for -p option.
374a5f0fb15SPaul Saab  */
375a5f0fb15SPaul Saab 	public void
376f6b74a7dSXin LI opt_p(type, s)
377f6b74a7dSXin LI 	int type;
378f6b74a7dSXin LI 	char *s;
379a5f0fb15SPaul Saab {
380a5f0fb15SPaul Saab 	switch (type)
381a5f0fb15SPaul Saab 	{
382a5f0fb15SPaul Saab 	case INIT:
383a5f0fb15SPaul Saab 		/*
384a15691bfSXin LI 		 * Unget a command for the specified string.
385a5f0fb15SPaul Saab 		 */
386a15691bfSXin LI 		if (less_is_more)
387a15691bfSXin LI 		{
3886dcb072bSXin LI 			/*
3896dcb072bSXin LI 			 * In "more" mode, the -p argument is a command,
3906dcb072bSXin LI 			 * not a search string, so we don't need a slash.
3916dcb072bSXin LI 			 */
392a15691bfSXin LI 			every_first_cmd = save(s);
393a15691bfSXin LI 		} else
394a15691bfSXin LI 		{
395a15691bfSXin LI 			plusoption = TRUE;
396a15691bfSXin LI 			ungetcc(CHAR_END_COMMAND);
397a15691bfSXin LI 			ungetsc(s);
398a15691bfSXin LI 			 /*
399a15691bfSXin LI 			  * {{ This won't work if the "/" command is
400a15691bfSXin LI 			  *    changed or invalidated by a .lesskey file. }}
401a15691bfSXin LI 			  */
402a5f0fb15SPaul Saab 			ungetsc("/");
403a15691bfSXin LI 		}
404a5f0fb15SPaul Saab 		break;
405a5f0fb15SPaul Saab 	}
406a5f0fb15SPaul Saab }
407a5f0fb15SPaul Saab 
408a5f0fb15SPaul Saab /*
409a5f0fb15SPaul Saab  * Handler for -P option.
410a5f0fb15SPaul Saab  */
411a5f0fb15SPaul Saab 	public void
412f6b74a7dSXin LI opt__P(type, s)
413f6b74a7dSXin LI 	int type;
414f6b74a7dSXin LI 	char *s;
415a5f0fb15SPaul Saab {
4161ea31627SRobert Watson 	char **proto;
417a5f0fb15SPaul Saab 	PARG parg;
418a5f0fb15SPaul Saab 
419a5f0fb15SPaul Saab 	switch (type)
420a5f0fb15SPaul Saab 	{
421a5f0fb15SPaul Saab 	case INIT:
422a5f0fb15SPaul Saab 	case TOGGLE:
423a5f0fb15SPaul Saab 		/*
424a5f0fb15SPaul Saab 		 * Figure out which prototype string should be changed.
425a5f0fb15SPaul Saab 		 */
426a5f0fb15SPaul Saab 		switch (*s)
427a5f0fb15SPaul Saab 		{
428a5f0fb15SPaul Saab 		case 's':  proto = &prproto[PR_SHORT];	s++;	break;
429a5f0fb15SPaul Saab 		case 'm':  proto = &prproto[PR_MEDIUM];	s++;	break;
430a5f0fb15SPaul Saab 		case 'M':  proto = &prproto[PR_LONG];	s++;	break;
431a5f0fb15SPaul Saab 		case '=':  proto = &eqproto;		s++;	break;
432a5f0fb15SPaul Saab 		case 'h':  proto = &hproto;		s++;	break;
433c9346414SPaul Saab 		case 'w':  proto = &wproto;		s++;	break;
434a5f0fb15SPaul Saab 		default:   proto = &prproto[PR_SHORT];		break;
435a5f0fb15SPaul Saab 		}
436a5f0fb15SPaul Saab 		free(*proto);
437a5f0fb15SPaul Saab 		*proto = save(s);
438a5f0fb15SPaul Saab 		break;
439a5f0fb15SPaul Saab 	case QUERY:
440a5f0fb15SPaul Saab 		parg.p_string = prproto[pr_type];
441a5f0fb15SPaul Saab 		error("%s", &parg);
442a5f0fb15SPaul Saab 		break;
443a5f0fb15SPaul Saab 	}
444a5f0fb15SPaul Saab }
445a5f0fb15SPaul Saab 
446a5f0fb15SPaul Saab /*
447a5f0fb15SPaul Saab  * Handler for the -b option.
448a5f0fb15SPaul Saab  */
449a5f0fb15SPaul Saab 	/*ARGSUSED*/
450a5f0fb15SPaul Saab 	public void
451f6b74a7dSXin LI opt_b(type, s)
452f6b74a7dSXin LI 	int type;
453f6b74a7dSXin LI 	char *s;
454a5f0fb15SPaul Saab {
455a5f0fb15SPaul Saab 	switch (type)
456a5f0fb15SPaul Saab 	{
457a5f0fb15SPaul Saab 	case INIT:
458000ba3e8STim J. Robbins 	case TOGGLE:
459000ba3e8STim J. Robbins 		/*
460000ba3e8STim J. Robbins 		 * Set the new number of buffers.
461000ba3e8STim J. Robbins 		 */
462000ba3e8STim J. Robbins 		ch_setbufspace(bufspace);
463000ba3e8STim J. Robbins 		break;
464000ba3e8STim J. Robbins 	case QUERY:
465a5f0fb15SPaul Saab 		break;
466a5f0fb15SPaul Saab 	}
467a5f0fb15SPaul Saab }
468a5f0fb15SPaul Saab 
469a5f0fb15SPaul Saab /*
470a5f0fb15SPaul Saab  * Handler for the -i option.
471a5f0fb15SPaul Saab  */
472a5f0fb15SPaul Saab 	/*ARGSUSED*/
473a5f0fb15SPaul Saab 	public void
474f6b74a7dSXin LI opt_i(type, s)
475f6b74a7dSXin LI 	int type;
476f6b74a7dSXin LI 	char *s;
477a5f0fb15SPaul Saab {
478a5f0fb15SPaul Saab 	switch (type)
479a5f0fb15SPaul Saab 	{
480a5f0fb15SPaul Saab 	case TOGGLE:
481a5f0fb15SPaul Saab 		chg_caseless();
482a5f0fb15SPaul Saab 		break;
483a5f0fb15SPaul Saab 	case QUERY:
484a5f0fb15SPaul Saab 	case INIT:
485a5f0fb15SPaul Saab 		break;
486a5f0fb15SPaul Saab 	}
487a5f0fb15SPaul Saab }
488a5f0fb15SPaul Saab 
489a5f0fb15SPaul Saab /*
490a5f0fb15SPaul Saab  * Handler for the -V option.
491a5f0fb15SPaul Saab  */
492a5f0fb15SPaul Saab 	/*ARGSUSED*/
493a5f0fb15SPaul Saab 	public void
494f6b74a7dSXin LI opt__V(type, s)
495f6b74a7dSXin LI 	int type;
496f6b74a7dSXin LI 	char *s;
497a5f0fb15SPaul Saab {
498a5f0fb15SPaul Saab 	switch (type)
499a5f0fb15SPaul Saab 	{
500a5f0fb15SPaul Saab 	case TOGGLE:
501a5f0fb15SPaul Saab 	case QUERY:
502a5f0fb15SPaul Saab 		dispversion();
503a5f0fb15SPaul Saab 		break;
504a5f0fb15SPaul Saab 	case INIT:
505a5f0fb15SPaul Saab 		/*
506a5f0fb15SPaul Saab 		 * Force output to stdout per GNU standard for --version output.
507a5f0fb15SPaul Saab 		 */
508a5f0fb15SPaul Saab 		any_display = 1;
509a5f0fb15SPaul Saab 		putstr("less ");
510a5f0fb15SPaul Saab 		putstr(version);
51196e55cc7SXin LI 		putstr(" (");
51296e55cc7SXin LI #if HAVE_GNU_REGEX
51396e55cc7SXin LI 		putstr("GNU ");
51496e55cc7SXin LI #endif
51596e55cc7SXin LI #if HAVE_POSIX_REGCOMP
51696e55cc7SXin LI 		putstr("POSIX ");
51796e55cc7SXin LI #endif
51896e55cc7SXin LI #if HAVE_PCRE
51996e55cc7SXin LI 		putstr("PCRE ");
52096e55cc7SXin LI #endif
52196e55cc7SXin LI #if HAVE_RE_COMP
52296e55cc7SXin LI 		putstr("BSD ");
52396e55cc7SXin LI #endif
52496e55cc7SXin LI #if HAVE_REGCMP
52596e55cc7SXin LI 		putstr("V8 ");
52696e55cc7SXin LI #endif
52796e55cc7SXin LI #if HAVE_V8_REGCOMP
52896e55cc7SXin LI 		putstr("Spencer V8 ");
52996e55cc7SXin LI #endif
53096e55cc7SXin LI #if !HAVE_GNU_REGEX && !HAVE_POSIX_REGCOMP && !HAVE_PCRE && !HAVE_RE_COMP && !HAVE_REGCMP && !HAVE_V8_REGCOMP
53196e55cc7SXin LI 		putstr("no ");
53296e55cc7SXin LI #endif
53396e55cc7SXin LI 		putstr("regular expressions)\n");
534f6b74a7dSXin LI 		putstr("Copyright (C) 1984-2017  Mark Nudelman\n\n");
535a5f0fb15SPaul Saab 		putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
536a5f0fb15SPaul Saab 		putstr("For information about the terms of redistribution,\n");
537a5f0fb15SPaul Saab 		putstr("see the file named README in the less distribution.\n");
538c9346414SPaul Saab 		putstr("Homepage: http://www.greenwoodsoftware.com/less\n");
539a5f0fb15SPaul Saab 		quit(QUIT_OK);
540a5f0fb15SPaul Saab 		break;
541a5f0fb15SPaul Saab 	}
542a5f0fb15SPaul Saab }
543a5f0fb15SPaul Saab 
544a5f0fb15SPaul Saab #if MSDOS_COMPILER
545a5f0fb15SPaul Saab /*
546a5f0fb15SPaul Saab  * Parse an MSDOS color descriptor.
547a5f0fb15SPaul Saab  */
548a5f0fb15SPaul Saab    	static void
549f6b74a7dSXin LI colordesc(s, fg_color, bg_color)
550f6b74a7dSXin LI 	char *s;
551f6b74a7dSXin LI 	int *fg_color;
552f6b74a7dSXin LI 	int *bg_color;
553a5f0fb15SPaul Saab {
554a5f0fb15SPaul Saab 	int fg, bg;
555a5f0fb15SPaul Saab 	int err;
556*b2ea2440SXin LI #if MSDOS_COMPILER==WIN32C
557*b2ea2440SXin LI 	int ul = 0;
558a5f0fb15SPaul Saab 
559*b2ea2440SXin LI 	if (*s == 'u')
560*b2ea2440SXin LI 	{
561*b2ea2440SXin LI 		ul = COMMON_LVB_UNDERSCORE;
562*b2ea2440SXin LI 		++s;
563*b2ea2440SXin LI 	}
564*b2ea2440SXin LI #endif
565000ba3e8STim J. Robbins 	fg = getnum(&s, "D", &err);
566a5f0fb15SPaul Saab 	if (err)
567a5f0fb15SPaul Saab 	{
568*b2ea2440SXin LI #if MSDOS_COMPILER==WIN32C
569*b2ea2440SXin LI 		if (ul)
570*b2ea2440SXin LI 			fg = nm_fg_color;
571*b2ea2440SXin LI 		else
572*b2ea2440SXin LI #endif
573*b2ea2440SXin LI 		{
574a5f0fb15SPaul Saab 			error("Missing fg color in -D", NULL_PARG);
575a5f0fb15SPaul Saab 			return;
576a5f0fb15SPaul Saab 		}
577*b2ea2440SXin LI 	}
578a5f0fb15SPaul Saab 	if (*s != '.')
5797374caaaSXin LI 		bg = nm_bg_color;
580a5f0fb15SPaul Saab 	else
581a5f0fb15SPaul Saab 	{
582a5f0fb15SPaul Saab 		s++;
583000ba3e8STim J. Robbins 		bg = getnum(&s, "D", &err);
584a5f0fb15SPaul Saab 		if (err)
585a5f0fb15SPaul Saab 		{
5867374caaaSXin LI 			error("Missing bg color in -D", NULL_PARG);
587a5f0fb15SPaul Saab 			return;
588a5f0fb15SPaul Saab 		}
589a5f0fb15SPaul Saab 	}
590*b2ea2440SXin LI #if MSDOS_COMPILER==WIN32C
591*b2ea2440SXin LI 	if (*s == 'u')
592*b2ea2440SXin LI 	{
593*b2ea2440SXin LI 		ul = COMMON_LVB_UNDERSCORE;
594*b2ea2440SXin LI 		++s;
595*b2ea2440SXin LI 	}
596*b2ea2440SXin LI 	fg |= ul;
597*b2ea2440SXin LI #endif
598a5f0fb15SPaul Saab 	if (*s != '\0')
599a5f0fb15SPaul Saab 		error("Extra characters at end of -D option", NULL_PARG);
600a5f0fb15SPaul Saab 	*fg_color = fg;
601a5f0fb15SPaul Saab 	*bg_color = bg;
602a5f0fb15SPaul Saab }
603a5f0fb15SPaul Saab 
604a5f0fb15SPaul Saab /*
605a5f0fb15SPaul Saab  * Handler for the -D option.
606a5f0fb15SPaul Saab  */
607a5f0fb15SPaul Saab 	/*ARGSUSED*/
608a5f0fb15SPaul Saab 	public void
609f6b74a7dSXin LI opt_D(type, s)
610f6b74a7dSXin LI 	int type;
611f6b74a7dSXin LI 	char *s;
612a5f0fb15SPaul Saab {
613f6b74a7dSXin LI 	PARG p;
614f6b74a7dSXin LI 
615a5f0fb15SPaul Saab 	switch (type)
616a5f0fb15SPaul Saab 	{
617a5f0fb15SPaul Saab 	case INIT:
618a5f0fb15SPaul Saab 	case TOGGLE:
619a5f0fb15SPaul Saab 		switch (*s++)
620a5f0fb15SPaul Saab 		{
621a5f0fb15SPaul Saab 		case 'n':
622a5f0fb15SPaul Saab 			colordesc(s, &nm_fg_color, &nm_bg_color);
623a5f0fb15SPaul Saab 			break;
624a5f0fb15SPaul Saab 		case 'd':
625a5f0fb15SPaul Saab 			colordesc(s, &bo_fg_color, &bo_bg_color);
626a5f0fb15SPaul Saab 			break;
627a5f0fb15SPaul Saab 		case 'u':
628a5f0fb15SPaul Saab 			colordesc(s, &ul_fg_color, &ul_bg_color);
629a5f0fb15SPaul Saab 			break;
630a5f0fb15SPaul Saab 		case 'k':
631a5f0fb15SPaul Saab 			colordesc(s, &bl_fg_color, &bl_bg_color);
632a5f0fb15SPaul Saab 			break;
633a5f0fb15SPaul Saab 		case 's':
634a5f0fb15SPaul Saab 			colordesc(s, &so_fg_color, &so_bg_color);
635a5f0fb15SPaul Saab 			break;
636f6b74a7dSXin LI 		case 'a':
637f6b74a7dSXin LI 			sgr_mode = !sgr_mode;
638f6b74a7dSXin LI 			break;
639a5f0fb15SPaul Saab 		default:
640f6b74a7dSXin LI 			error("-D must be followed by n, d, u, k, s or a", NULL_PARG);
641a5f0fb15SPaul Saab 			break;
642a5f0fb15SPaul Saab 		}
643a5f0fb15SPaul Saab 		if (type == TOGGLE)
644a5f0fb15SPaul Saab 		{
6456dcb072bSXin LI 			at_enter(AT_STANDOUT);
6466dcb072bSXin LI 			at_exit();
647a5f0fb15SPaul Saab 		}
648a5f0fb15SPaul Saab 		break;
649a5f0fb15SPaul Saab 	case QUERY:
650f6b74a7dSXin LI 		p.p_string = (sgr_mode) ? "on" : "off";
651f6b74a7dSXin LI 		error("SGR mode is %s", &p);
652a5f0fb15SPaul Saab 		break;
653a5f0fb15SPaul Saab 	}
654a5f0fb15SPaul Saab }
655a5f0fb15SPaul Saab #endif
656a5f0fb15SPaul Saab 
657a5f0fb15SPaul Saab /*
658c9346414SPaul Saab  * Handler for the -x option.
659c9346414SPaul Saab  */
660c9346414SPaul Saab 	public void
661f6b74a7dSXin LI opt_x(type, s)
662f6b74a7dSXin LI 	int type;
663f6b74a7dSXin LI 	char *s;
664c9346414SPaul Saab {
665c9346414SPaul Saab 	extern int tabstops[];
666c9346414SPaul Saab 	extern int ntabstops;
667c9346414SPaul Saab 	extern int tabdefault;
668c9346414SPaul Saab 	char msg[60+(4*TABSTOP_MAX)];
669c9346414SPaul Saab 	int i;
670c9346414SPaul Saab 	PARG p;
671c9346414SPaul Saab 
672c9346414SPaul Saab 	switch (type)
673c9346414SPaul Saab 	{
674c9346414SPaul Saab 	case INIT:
675c9346414SPaul Saab 	case TOGGLE:
676c9346414SPaul Saab 		/* Start at 1 because tabstops[0] is always zero. */
677c9346414SPaul Saab 		for (i = 1;  i < TABSTOP_MAX;  )
678c9346414SPaul Saab 		{
679c9346414SPaul Saab 			int n = 0;
680000ba3e8STim J. Robbins 			s = skipsp(s);
681c9346414SPaul Saab 			while (*s >= '0' && *s <= '9')
682c9346414SPaul Saab 				n = (10 * n) + (*s++ - '0');
683c9346414SPaul Saab 			if (n > tabstops[i-1])
684c9346414SPaul Saab 				tabstops[i++] = n;
685000ba3e8STim J. Robbins 			s = skipsp(s);
686c9346414SPaul Saab 			if (*s++ != ',')
687c9346414SPaul Saab 				break;
688c9346414SPaul Saab 		}
689c9346414SPaul Saab 		if (i < 2)
690c9346414SPaul Saab 			return;
691c9346414SPaul Saab 		ntabstops = i;
692c9346414SPaul Saab 		tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
693c9346414SPaul Saab 		break;
694c9346414SPaul Saab 	case QUERY:
695c9346414SPaul Saab 		strcpy(msg, "Tab stops ");
696c9346414SPaul Saab 		if (ntabstops > 2)
697c9346414SPaul Saab 		{
698c9346414SPaul Saab 			for (i = 1;  i < ntabstops;  i++)
699c9346414SPaul Saab 			{
700c9346414SPaul Saab 				if (i > 1)
701c9346414SPaul Saab 					strcat(msg, ",");
702c9346414SPaul Saab 				sprintf(msg+strlen(msg), "%d", tabstops[i]);
703c9346414SPaul Saab 			}
704c9346414SPaul Saab 			sprintf(msg+strlen(msg), " and then ");
705c9346414SPaul Saab 		}
706c9346414SPaul Saab 		sprintf(msg+strlen(msg), "every %d spaces",
707c9346414SPaul Saab 			tabdefault);
708c9346414SPaul Saab 		p.p_string = msg;
709c9346414SPaul Saab 		error("%s", &p);
710c9346414SPaul Saab 		break;
711c9346414SPaul Saab 	}
712c9346414SPaul Saab }
713c9346414SPaul Saab 
714c9346414SPaul Saab 
715c9346414SPaul Saab /*
716a5f0fb15SPaul Saab  * Handler for the -" option.
717a5f0fb15SPaul Saab  */
718a5f0fb15SPaul Saab 	public void
719f6b74a7dSXin LI opt_quote(type, s)
720f6b74a7dSXin LI 	int type;
721f6b74a7dSXin LI 	char *s;
722a5f0fb15SPaul Saab {
723a5f0fb15SPaul Saab 	char buf[3];
724a5f0fb15SPaul Saab 	PARG parg;
725a5f0fb15SPaul Saab 
726a5f0fb15SPaul Saab 	switch (type)
727a5f0fb15SPaul Saab 	{
728a5f0fb15SPaul Saab 	case INIT:
729a5f0fb15SPaul Saab 	case TOGGLE:
730000ba3e8STim J. Robbins 		if (s[0] == '\0')
731000ba3e8STim J. Robbins 		{
732000ba3e8STim J. Robbins 			openquote = closequote = '\0';
733000ba3e8STim J. Robbins 			break;
734000ba3e8STim J. Robbins 		}
735a5f0fb15SPaul Saab 		if (s[1] != '\0' && s[2] != '\0')
736a5f0fb15SPaul Saab 		{
737a5f0fb15SPaul Saab 			error("-\" must be followed by 1 or 2 chars", NULL_PARG);
738a5f0fb15SPaul Saab 			return;
739a5f0fb15SPaul Saab 		}
740a5f0fb15SPaul Saab 		openquote = s[0];
741a5f0fb15SPaul Saab 		if (s[1] == '\0')
742a5f0fb15SPaul Saab 			closequote = openquote;
743a5f0fb15SPaul Saab 		else
744a5f0fb15SPaul Saab 			closequote = s[1];
745a5f0fb15SPaul Saab 		break;
746a5f0fb15SPaul Saab 	case QUERY:
747a5f0fb15SPaul Saab 		buf[0] = openquote;
748a5f0fb15SPaul Saab 		buf[1] = closequote;
749a5f0fb15SPaul Saab 		buf[2] = '\0';
750a5f0fb15SPaul Saab 		parg.p_string = buf;
751a5f0fb15SPaul Saab 		error("quotes %s", &parg);
752a5f0fb15SPaul Saab 		break;
753a5f0fb15SPaul Saab 	}
754a5f0fb15SPaul Saab }
755a5f0fb15SPaul Saab 
756a5f0fb15SPaul Saab /*
757*b2ea2440SXin LI  * Handler for the --rscroll option.
758*b2ea2440SXin LI  */
759*b2ea2440SXin LI 	/*ARGSUSED*/
760*b2ea2440SXin LI 	public void
761*b2ea2440SXin LI opt_rscroll(type, s)
762*b2ea2440SXin LI 	int type;
763*b2ea2440SXin LI 	char *s;
764*b2ea2440SXin LI {
765*b2ea2440SXin LI 	PARG p;
766*b2ea2440SXin LI 
767*b2ea2440SXin LI 	switch (type)
768*b2ea2440SXin LI 	{
769*b2ea2440SXin LI 	case INIT:
770*b2ea2440SXin LI 	case TOGGLE: {
771*b2ea2440SXin LI 		char *fmt;
772*b2ea2440SXin LI 		int attr = AT_STANDOUT;
773*b2ea2440SXin LI 		setfmt(s, &fmt, &attr, "*s>");
774*b2ea2440SXin LI 		if (strcmp(fmt, "-") == 0)
775*b2ea2440SXin LI 		{
776*b2ea2440SXin LI 			rscroll_char = 0;
777*b2ea2440SXin LI 		} else
778*b2ea2440SXin LI 		{
779*b2ea2440SXin LI 			rscroll_char = *fmt ? *fmt : '>';
780*b2ea2440SXin LI 			rscroll_attr = attr;
781*b2ea2440SXin LI 		}
782*b2ea2440SXin LI 		break; }
783*b2ea2440SXin LI 	case QUERY: {
784*b2ea2440SXin LI 		p.p_string = rscroll_char ? prchar(rscroll_char) : "-";
785*b2ea2440SXin LI 		error("rscroll char is %s", &p);
786*b2ea2440SXin LI 		break; }
787*b2ea2440SXin LI 	}
788*b2ea2440SXin LI }
789*b2ea2440SXin LI 
790*b2ea2440SXin LI /*
791a5f0fb15SPaul Saab  * "-?" means display a help message.
792a5f0fb15SPaul Saab  * If from the command line, exit immediately.
793a5f0fb15SPaul Saab  */
794a5f0fb15SPaul Saab 	/*ARGSUSED*/
795a5f0fb15SPaul Saab 	public void
796f6b74a7dSXin LI opt_query(type, s)
797f6b74a7dSXin LI 	int type;
798f6b74a7dSXin LI 	char *s;
799a5f0fb15SPaul Saab {
800a5f0fb15SPaul Saab 	switch (type)
801a5f0fb15SPaul Saab 	{
802a5f0fb15SPaul Saab 	case QUERY:
803a5f0fb15SPaul Saab 	case TOGGLE:
804a5f0fb15SPaul Saab 		error("Use \"h\" for help", NULL_PARG);
805a5f0fb15SPaul Saab 		break;
806a5f0fb15SPaul Saab 	case INIT:
807a5f0fb15SPaul Saab 		dohelp = 1;
808a5f0fb15SPaul Saab 	}
809a5f0fb15SPaul Saab }
810a5f0fb15SPaul Saab 
811a5f0fb15SPaul Saab /*
812a5f0fb15SPaul Saab  * Get the "screen window" size.
813a5f0fb15SPaul Saab  */
814a5f0fb15SPaul Saab 	public int
815f6b74a7dSXin LI get_swindow()
816a5f0fb15SPaul Saab {
817a5f0fb15SPaul Saab 	if (swindow > 0)
818a5f0fb15SPaul Saab 		return (swindow);
819a5f0fb15SPaul Saab 	return (sc_height + swindow);
820a5f0fb15SPaul Saab }
821a5f0fb15SPaul Saab 
822