xref: /minix3/external/bsd/less/dist/optfunc.c (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc /*	$NetBSD: optfunc.c,v 1.3 2013/09/04 19:44:21 tron Exp $	*/
2f7cf2976SLionel Sambuc 
3f7cf2976SLionel Sambuc /*
4*84d9c625SLionel Sambuc  * Copyright (C) 1984-2012  Mark Nudelman
5f7cf2976SLionel Sambuc  *
6f7cf2976SLionel Sambuc  * You may distribute under the terms of either the GNU General Public
7f7cf2976SLionel Sambuc  * License or the Less License, as specified in the README file.
8f7cf2976SLionel Sambuc  *
9*84d9c625SLionel Sambuc  * For more information, see the README file.
10f7cf2976SLionel Sambuc  */
11f7cf2976SLionel Sambuc 
12f7cf2976SLionel Sambuc 
13f7cf2976SLionel Sambuc /*
14f7cf2976SLionel Sambuc  * Handling functions for command line options.
15f7cf2976SLionel Sambuc  *
16f7cf2976SLionel Sambuc  * Most options are handled by the generic code in option.c.
17f7cf2976SLionel Sambuc  * But all string options, and a few non-string options, require
18f7cf2976SLionel Sambuc  * special handling specific to the particular option.
19f7cf2976SLionel Sambuc  * This special processing is done by the "handling functions" in this file.
20f7cf2976SLionel Sambuc  *
21f7cf2976SLionel Sambuc  * Each handling function is passed a "type" and, if it is a string
22f7cf2976SLionel Sambuc  * option, the string which should be "assigned" to the option.
23f7cf2976SLionel Sambuc  * The type may be one of:
24f7cf2976SLionel Sambuc  *	INIT	The option is being initialized from the command line.
25f7cf2976SLionel Sambuc  *	TOGGLE	The option is being changed from within the program.
26f7cf2976SLionel Sambuc  *	QUERY	The setting of the option is merely being queried.
27f7cf2976SLionel Sambuc  */
28f7cf2976SLionel Sambuc 
29f7cf2976SLionel Sambuc #include "less.h"
30f7cf2976SLionel Sambuc #include "option.h"
31f7cf2976SLionel Sambuc 
32f7cf2976SLionel Sambuc extern int nbufs;
33f7cf2976SLionel Sambuc extern int bufspace;
34f7cf2976SLionel Sambuc extern int pr_type;
35f7cf2976SLionel Sambuc extern int plusoption;
36f7cf2976SLionel Sambuc extern int swindow;
37f7cf2976SLionel Sambuc extern int sc_width;
38f7cf2976SLionel Sambuc extern int sc_height;
39f7cf2976SLionel Sambuc extern int secure;
40f7cf2976SLionel Sambuc extern int dohelp;
41f7cf2976SLionel Sambuc extern int any_display;
42f7cf2976SLionel Sambuc extern char openquote;
43f7cf2976SLionel Sambuc extern char closequote;
44f7cf2976SLionel Sambuc extern char *prproto[];
45f7cf2976SLionel Sambuc extern char *eqproto;
46f7cf2976SLionel Sambuc extern char *hproto;
47f7cf2976SLionel Sambuc extern char *wproto;
48f7cf2976SLionel Sambuc extern IFILE curr_ifile;
49f7cf2976SLionel Sambuc extern char version[];
50f7cf2976SLionel Sambuc extern int jump_sline;
51f7cf2976SLionel Sambuc extern int jump_sline_fraction;
52f7cf2976SLionel Sambuc extern int shift_count;
53f7cf2976SLionel Sambuc extern int shift_count_fraction;
54f7cf2976SLionel Sambuc extern int less_is_more;
55f7cf2976SLionel Sambuc #if LOGFILE
56f7cf2976SLionel Sambuc extern char *namelogfile;
57f7cf2976SLionel Sambuc extern int force_logfile;
58f7cf2976SLionel Sambuc extern int logfile;
59f7cf2976SLionel Sambuc #endif
60f7cf2976SLionel Sambuc #if TAGS
61f7cf2976SLionel Sambuc public char *tagoption = NULL;
62f7cf2976SLionel Sambuc extern char *tags;
63f7cf2976SLionel Sambuc #endif
64f7cf2976SLionel Sambuc #if MSDOS_COMPILER
65f7cf2976SLionel Sambuc extern int nm_fg_color, nm_bg_color;
66f7cf2976SLionel Sambuc extern int bo_fg_color, bo_bg_color;
67f7cf2976SLionel Sambuc extern int ul_fg_color, ul_bg_color;
68f7cf2976SLionel Sambuc extern int so_fg_color, so_bg_color;
69f7cf2976SLionel Sambuc extern int bl_fg_color, bl_bg_color;
70f7cf2976SLionel Sambuc #endif
71f7cf2976SLionel Sambuc 
72f7cf2976SLionel Sambuc 
73f7cf2976SLionel Sambuc #if LOGFILE
74f7cf2976SLionel Sambuc /*
75f7cf2976SLionel Sambuc  * Handler for -o option.
76f7cf2976SLionel Sambuc  */
77f7cf2976SLionel Sambuc 	public void
opt_o(type,s)78f7cf2976SLionel Sambuc opt_o(type, s)
79f7cf2976SLionel Sambuc 	int type;
80f7cf2976SLionel Sambuc 	char *s;
81f7cf2976SLionel Sambuc {
82f7cf2976SLionel Sambuc 	PARG parg;
83f7cf2976SLionel Sambuc 
84f7cf2976SLionel Sambuc 	if (secure)
85f7cf2976SLionel Sambuc 	{
86f7cf2976SLionel Sambuc 		error("log file support is not available", NULL_PARG);
87f7cf2976SLionel Sambuc 		return;
88f7cf2976SLionel Sambuc 	}
89f7cf2976SLionel Sambuc 	switch (type)
90f7cf2976SLionel Sambuc 	{
91f7cf2976SLionel Sambuc 	case INIT:
92f7cf2976SLionel Sambuc 		namelogfile = s;
93f7cf2976SLionel Sambuc 		break;
94f7cf2976SLionel Sambuc 	case TOGGLE:
95f7cf2976SLionel Sambuc 		if (ch_getflags() & CH_CANSEEK)
96f7cf2976SLionel Sambuc 		{
97f7cf2976SLionel Sambuc 			error("Input is not a pipe", NULL_PARG);
98f7cf2976SLionel Sambuc 			return;
99f7cf2976SLionel Sambuc 		}
100f7cf2976SLionel Sambuc 		if (logfile >= 0)
101f7cf2976SLionel Sambuc 		{
102f7cf2976SLionel Sambuc 			error("Log file is already in use", NULL_PARG);
103f7cf2976SLionel Sambuc 			return;
104f7cf2976SLionel Sambuc 		}
105f7cf2976SLionel Sambuc 		s = skipsp(s);
106f7cf2976SLionel Sambuc 		namelogfile = lglob(s);
107f7cf2976SLionel Sambuc 		use_logfile(namelogfile);
108f7cf2976SLionel Sambuc 		sync_logfile();
109f7cf2976SLionel Sambuc 		break;
110f7cf2976SLionel Sambuc 	case QUERY:
111f7cf2976SLionel Sambuc 		if (logfile < 0)
112f7cf2976SLionel Sambuc 			error("No log file", NULL_PARG);
113f7cf2976SLionel Sambuc 		else
114f7cf2976SLionel Sambuc 		{
115f7cf2976SLionel Sambuc 			parg.p_string = namelogfile;
116f7cf2976SLionel Sambuc 			error("Log file \"%s\"", &parg);
117f7cf2976SLionel Sambuc 		}
118f7cf2976SLionel Sambuc 		break;
119f7cf2976SLionel Sambuc 	}
120f7cf2976SLionel Sambuc }
121f7cf2976SLionel Sambuc 
122f7cf2976SLionel Sambuc /*
123f7cf2976SLionel Sambuc  * Handler for -O option.
124f7cf2976SLionel Sambuc  */
125f7cf2976SLionel Sambuc 	public void
opt__O(type,s)126f7cf2976SLionel Sambuc opt__O(type, s)
127f7cf2976SLionel Sambuc 	int type;
128f7cf2976SLionel Sambuc 	char *s;
129f7cf2976SLionel Sambuc {
130f7cf2976SLionel Sambuc 	force_logfile = TRUE;
131f7cf2976SLionel Sambuc 	opt_o(type, s);
132f7cf2976SLionel Sambuc }
133f7cf2976SLionel Sambuc #endif
134f7cf2976SLionel Sambuc 
135f7cf2976SLionel Sambuc /*
136f7cf2976SLionel Sambuc  * Handlers for -j option.
137f7cf2976SLionel Sambuc  */
138f7cf2976SLionel Sambuc 	public void
opt_j(type,s)139f7cf2976SLionel Sambuc opt_j(type, s)
140f7cf2976SLionel Sambuc 	int type;
141f7cf2976SLionel Sambuc 	char *s;
142f7cf2976SLionel Sambuc {
143f7cf2976SLionel Sambuc 	PARG parg;
144f7cf2976SLionel Sambuc 	char buf[16];
145f7cf2976SLionel Sambuc 	int len;
146f7cf2976SLionel Sambuc 	int err;
147f7cf2976SLionel Sambuc 
148f7cf2976SLionel Sambuc 	switch (type)
149f7cf2976SLionel Sambuc 	{
150f7cf2976SLionel Sambuc 	case INIT:
151f7cf2976SLionel Sambuc 	case TOGGLE:
152f7cf2976SLionel Sambuc 		if (*s == '.')
153f7cf2976SLionel Sambuc 		{
154f7cf2976SLionel Sambuc 			s++;
155f7cf2976SLionel Sambuc 			jump_sline_fraction = getfraction(&s, "j", &err);
156f7cf2976SLionel Sambuc 			if (err)
157f7cf2976SLionel Sambuc 				error("Invalid line fraction", NULL_PARG);
158f7cf2976SLionel Sambuc 			else
159f7cf2976SLionel Sambuc 				calc_jump_sline();
160f7cf2976SLionel Sambuc 		} else
161f7cf2976SLionel Sambuc 		{
162f7cf2976SLionel Sambuc 			int sline = getnum(&s, "j", &err);
163f7cf2976SLionel Sambuc 			if (err)
164f7cf2976SLionel Sambuc 				error("Invalid line number", NULL_PARG);
165f7cf2976SLionel Sambuc 			else
166f7cf2976SLionel Sambuc 			{
167f7cf2976SLionel Sambuc 				jump_sline = sline;
168f7cf2976SLionel Sambuc 				jump_sline_fraction = -1;
169f7cf2976SLionel Sambuc 			}
170f7cf2976SLionel Sambuc 		}
171f7cf2976SLionel Sambuc 		break;
172f7cf2976SLionel Sambuc 	case QUERY:
173f7cf2976SLionel Sambuc 		if (jump_sline_fraction < 0)
174f7cf2976SLionel Sambuc 		{
175f7cf2976SLionel Sambuc 			parg.p_int =  jump_sline;
176f7cf2976SLionel Sambuc 			error("Position target at screen line %d", &parg);
177f7cf2976SLionel Sambuc 		} else
178f7cf2976SLionel Sambuc 		{
179f7cf2976SLionel Sambuc 
180f7cf2976SLionel Sambuc 			sprintf(buf, ".%06d", jump_sline_fraction);
181f7cf2976SLionel Sambuc 			len = strlen(buf);
182f7cf2976SLionel Sambuc 			while (len > 2 && buf[len-1] == '0')
183f7cf2976SLionel Sambuc 				len--;
184f7cf2976SLionel Sambuc 			buf[len] = '\0';
185f7cf2976SLionel Sambuc 			parg.p_string = buf;
186f7cf2976SLionel Sambuc 			error("Position target at screen position %s", &parg);
187f7cf2976SLionel Sambuc 		}
188f7cf2976SLionel Sambuc 		break;
189f7cf2976SLionel Sambuc 	}
190f7cf2976SLionel Sambuc }
191f7cf2976SLionel Sambuc 
192f7cf2976SLionel Sambuc 	public void
calc_jump_sline()193f7cf2976SLionel Sambuc calc_jump_sline()
194f7cf2976SLionel Sambuc {
195f7cf2976SLionel Sambuc 	if (jump_sline_fraction < 0)
196f7cf2976SLionel Sambuc 		return;
197f7cf2976SLionel Sambuc 	jump_sline = sc_height * jump_sline_fraction / NUM_FRAC_DENOM;
198f7cf2976SLionel Sambuc }
199f7cf2976SLionel Sambuc 
200f7cf2976SLionel Sambuc /*
201f7cf2976SLionel Sambuc  * Handlers for -# option.
202f7cf2976SLionel Sambuc  */
203f7cf2976SLionel Sambuc 	public void
opt_shift(type,s)204f7cf2976SLionel Sambuc opt_shift(type, s)
205f7cf2976SLionel Sambuc 	int type;
206f7cf2976SLionel Sambuc 	char *s;
207f7cf2976SLionel Sambuc {
208f7cf2976SLionel Sambuc 	PARG parg;
209f7cf2976SLionel Sambuc 	char buf[16];
210f7cf2976SLionel Sambuc 	int len;
211f7cf2976SLionel Sambuc 	int err;
212f7cf2976SLionel Sambuc 
213f7cf2976SLionel Sambuc 	switch (type)
214f7cf2976SLionel Sambuc 	{
215f7cf2976SLionel Sambuc 	case INIT:
216f7cf2976SLionel Sambuc 	case TOGGLE:
217f7cf2976SLionel Sambuc 		if (*s == '.')
218f7cf2976SLionel Sambuc 		{
219f7cf2976SLionel Sambuc 			s++;
220f7cf2976SLionel Sambuc 			shift_count_fraction = getfraction(&s, "#", &err);
221f7cf2976SLionel Sambuc 			if (err)
222f7cf2976SLionel Sambuc 				error("Invalid column fraction", NULL_PARG);
223f7cf2976SLionel Sambuc 			else
224f7cf2976SLionel Sambuc 				calc_shift_count();
225f7cf2976SLionel Sambuc 		} else
226f7cf2976SLionel Sambuc 		{
227f7cf2976SLionel Sambuc 			int hs = getnum(&s, "#", &err);
228f7cf2976SLionel Sambuc 			if (err)
229f7cf2976SLionel Sambuc 				error("Invalid column number", NULL_PARG);
230f7cf2976SLionel Sambuc 			else
231f7cf2976SLionel Sambuc 			{
232f7cf2976SLionel Sambuc 				shift_count = hs;
233f7cf2976SLionel Sambuc 				shift_count_fraction = -1;
234f7cf2976SLionel Sambuc 			}
235f7cf2976SLionel Sambuc 		}
236f7cf2976SLionel Sambuc 		break;
237f7cf2976SLionel Sambuc 	case QUERY:
238f7cf2976SLionel Sambuc 		if (shift_count_fraction < 0)
239f7cf2976SLionel Sambuc 		{
240f7cf2976SLionel Sambuc 			parg.p_int = shift_count;
241f7cf2976SLionel Sambuc 			error("Horizontal shift %d columns", &parg);
242f7cf2976SLionel Sambuc 		} else
243f7cf2976SLionel Sambuc 		{
244f7cf2976SLionel Sambuc 
245f7cf2976SLionel Sambuc 			sprintf(buf, ".%06d", shift_count_fraction);
246f7cf2976SLionel Sambuc 			len = strlen(buf);
247f7cf2976SLionel Sambuc 			while (len > 2 && buf[len-1] == '0')
248f7cf2976SLionel Sambuc 				len--;
249f7cf2976SLionel Sambuc 			buf[len] = '\0';
250f7cf2976SLionel Sambuc 			parg.p_string = buf;
251f7cf2976SLionel Sambuc 			error("Horizontal shift %s of screen width", &parg);
252f7cf2976SLionel Sambuc 		}
253f7cf2976SLionel Sambuc 		break;
254f7cf2976SLionel Sambuc 	}
255f7cf2976SLionel Sambuc }
256f7cf2976SLionel Sambuc 	public void
calc_shift_count()257f7cf2976SLionel Sambuc calc_shift_count()
258f7cf2976SLionel Sambuc {
259f7cf2976SLionel Sambuc 	if (shift_count_fraction < 0)
260f7cf2976SLionel Sambuc 		return;
261f7cf2976SLionel Sambuc 	shift_count = sc_width * shift_count_fraction / NUM_FRAC_DENOM;
262f7cf2976SLionel Sambuc }
263f7cf2976SLionel Sambuc 
264f7cf2976SLionel Sambuc #if USERFILE
265f7cf2976SLionel Sambuc 	public void
opt_k(type,s)266f7cf2976SLionel Sambuc opt_k(type, s)
267f7cf2976SLionel Sambuc 	int type;
268f7cf2976SLionel Sambuc 	char *s;
269f7cf2976SLionel Sambuc {
270f7cf2976SLionel Sambuc 	PARG parg;
271f7cf2976SLionel Sambuc 
272f7cf2976SLionel Sambuc 	switch (type)
273f7cf2976SLionel Sambuc 	{
274f7cf2976SLionel Sambuc 	case INIT:
275f7cf2976SLionel Sambuc 		if (lesskey(s, 0))
276f7cf2976SLionel Sambuc 		{
277f7cf2976SLionel Sambuc 			parg.p_string = s;
278f7cf2976SLionel Sambuc 			error("Cannot use lesskey file \"%s\"", &parg);
279f7cf2976SLionel Sambuc 		}
280f7cf2976SLionel Sambuc 		break;
281f7cf2976SLionel Sambuc 	}
282f7cf2976SLionel Sambuc }
283f7cf2976SLionel Sambuc #endif
284f7cf2976SLionel Sambuc 
285f7cf2976SLionel Sambuc #if TAGS
286f7cf2976SLionel Sambuc /*
287f7cf2976SLionel Sambuc  * Handler for -t option.
288f7cf2976SLionel Sambuc  */
289f7cf2976SLionel Sambuc 	public void
opt_t(type,s)290f7cf2976SLionel Sambuc opt_t(type, s)
291f7cf2976SLionel Sambuc 	int type;
292f7cf2976SLionel Sambuc 	char *s;
293f7cf2976SLionel Sambuc {
294f7cf2976SLionel Sambuc 	IFILE save_ifile;
295f7cf2976SLionel Sambuc 	POSITION pos;
296f7cf2976SLionel Sambuc 
297f7cf2976SLionel Sambuc 	switch (type)
298f7cf2976SLionel Sambuc 	{
299f7cf2976SLionel Sambuc 	case INIT:
300f7cf2976SLionel Sambuc 		tagoption = s;
301f7cf2976SLionel Sambuc 		/* Do the rest in main() */
302f7cf2976SLionel Sambuc 		break;
303f7cf2976SLionel Sambuc 	case TOGGLE:
304f7cf2976SLionel Sambuc 		if (secure)
305f7cf2976SLionel Sambuc 		{
306f7cf2976SLionel Sambuc 			error("tags support is not available", NULL_PARG);
307f7cf2976SLionel Sambuc 			break;
308f7cf2976SLionel Sambuc 		}
309f7cf2976SLionel Sambuc 		findtag(skipsp(s));
310f7cf2976SLionel Sambuc 		save_ifile = save_curr_ifile();
311f7cf2976SLionel Sambuc 		/*
312f7cf2976SLionel Sambuc 		 * Try to open the file containing the tag
313f7cf2976SLionel Sambuc 		 * and search for the tag in that file.
314f7cf2976SLionel Sambuc 		 */
315f7cf2976SLionel Sambuc 		if (edit_tagfile() || (pos = tagsearch()) == NULL_POSITION)
316f7cf2976SLionel Sambuc 		{
317f7cf2976SLionel Sambuc 			/* Failed: reopen the old file. */
318f7cf2976SLionel Sambuc 			reedit_ifile(save_ifile);
319f7cf2976SLionel Sambuc 			break;
320f7cf2976SLionel Sambuc 		}
321f7cf2976SLionel Sambuc 		unsave_ifile(save_ifile);
322f7cf2976SLionel Sambuc 		jump_loc(pos, jump_sline);
323f7cf2976SLionel Sambuc 		break;
324f7cf2976SLionel Sambuc 	}
325f7cf2976SLionel Sambuc }
326f7cf2976SLionel Sambuc 
327f7cf2976SLionel Sambuc /*
328f7cf2976SLionel Sambuc  * Handler for -T option.
329f7cf2976SLionel Sambuc  */
330f7cf2976SLionel Sambuc 	public void
opt__T(type,s)331f7cf2976SLionel Sambuc opt__T(type, s)
332f7cf2976SLionel Sambuc 	int type;
333f7cf2976SLionel Sambuc 	char *s;
334f7cf2976SLionel Sambuc {
335f7cf2976SLionel Sambuc 	PARG parg;
336f7cf2976SLionel Sambuc 
337f7cf2976SLionel Sambuc 	switch (type)
338f7cf2976SLionel Sambuc 	{
339f7cf2976SLionel Sambuc 	case INIT:
340f7cf2976SLionel Sambuc 		tags = s;
341f7cf2976SLionel Sambuc 		break;
342f7cf2976SLionel Sambuc 	case TOGGLE:
343f7cf2976SLionel Sambuc 		s = skipsp(s);
344f7cf2976SLionel Sambuc 		tags = lglob(s);
345f7cf2976SLionel Sambuc 		break;
346f7cf2976SLionel Sambuc 	case QUERY:
347f7cf2976SLionel Sambuc 		parg.p_string = tags;
348f7cf2976SLionel Sambuc 		error("Tags file \"%s\"", &parg);
349f7cf2976SLionel Sambuc 		break;
350f7cf2976SLionel Sambuc 	}
351f7cf2976SLionel Sambuc }
352f7cf2976SLionel Sambuc #endif
353f7cf2976SLionel Sambuc 
354f7cf2976SLionel Sambuc /*
355f7cf2976SLionel Sambuc  * Handler for -p option.
356f7cf2976SLionel Sambuc  */
357f7cf2976SLionel Sambuc 	public void
opt_p(type,s)358f7cf2976SLionel Sambuc opt_p(type, s)
359f7cf2976SLionel Sambuc 	int type;
360f7cf2976SLionel Sambuc 	register char *s;
361f7cf2976SLionel Sambuc {
362f7cf2976SLionel Sambuc 	switch (type)
363f7cf2976SLionel Sambuc 	{
364f7cf2976SLionel Sambuc 	case INIT:
365f7cf2976SLionel Sambuc 		/*
366f7cf2976SLionel Sambuc 		 * Unget a search command for the specified string.
367f7cf2976SLionel Sambuc 		 * {{ This won't work if the "/" command is
368f7cf2976SLionel Sambuc 		 *    changed or invalidated by a .lesskey file. }}
369f7cf2976SLionel Sambuc 		 */
370f7cf2976SLionel Sambuc 		plusoption = TRUE;
371f7cf2976SLionel Sambuc 		ungetsc(s);
372f7cf2976SLionel Sambuc 		/*
373f7cf2976SLionel Sambuc 		 * In "more" mode, the -p argument is a command,
374f7cf2976SLionel Sambuc 		 * not a search string, so we don't need a slash.
375f7cf2976SLionel Sambuc 		 */
376f7cf2976SLionel Sambuc 		if (!less_is_more)
377f7cf2976SLionel Sambuc 			ungetsc("/");
378f7cf2976SLionel Sambuc 		break;
379f7cf2976SLionel Sambuc 	}
380f7cf2976SLionel Sambuc }
381f7cf2976SLionel Sambuc 
382f7cf2976SLionel Sambuc /*
383f7cf2976SLionel Sambuc  * Handler for -P option.
384f7cf2976SLionel Sambuc  */
385f7cf2976SLionel Sambuc 	public void
opt__P(type,s)386f7cf2976SLionel Sambuc opt__P(type, s)
387f7cf2976SLionel Sambuc 	int type;
388f7cf2976SLionel Sambuc 	register char *s;
389f7cf2976SLionel Sambuc {
390f7cf2976SLionel Sambuc 	register char **proto;
391f7cf2976SLionel Sambuc 	PARG parg;
392f7cf2976SLionel Sambuc 
393f7cf2976SLionel Sambuc 	switch (type)
394f7cf2976SLionel Sambuc 	{
395f7cf2976SLionel Sambuc 	case INIT:
396f7cf2976SLionel Sambuc 	case TOGGLE:
397f7cf2976SLionel Sambuc 		/*
398f7cf2976SLionel Sambuc 		 * Figure out which prototype string should be changed.
399f7cf2976SLionel Sambuc 		 */
400f7cf2976SLionel Sambuc 		switch (*s)
401f7cf2976SLionel Sambuc 		{
402f7cf2976SLionel Sambuc 		case 's':  proto = &prproto[PR_SHORT];	s++;	break;
403f7cf2976SLionel Sambuc 		case 'm':  proto = &prproto[PR_MEDIUM];	s++;	break;
404f7cf2976SLionel Sambuc 		case 'M':  proto = &prproto[PR_LONG];	s++;	break;
405f7cf2976SLionel Sambuc 		case '=':  proto = &eqproto;		s++;	break;
406f7cf2976SLionel Sambuc 		case 'h':  proto = &hproto;		s++;	break;
407f7cf2976SLionel Sambuc 		case 'w':  proto = &wproto;		s++;	break;
408f7cf2976SLionel Sambuc 		default:   proto = &prproto[PR_SHORT];		break;
409f7cf2976SLionel Sambuc 		}
410f7cf2976SLionel Sambuc 		free(*proto);
411f7cf2976SLionel Sambuc 		*proto = save(s);
412f7cf2976SLionel Sambuc 		break;
413f7cf2976SLionel Sambuc 	case QUERY:
414f7cf2976SLionel Sambuc 		parg.p_string = prproto[pr_type];
415f7cf2976SLionel Sambuc 		error("%s", &parg);
416f7cf2976SLionel Sambuc 		break;
417f7cf2976SLionel Sambuc 	}
418f7cf2976SLionel Sambuc }
419f7cf2976SLionel Sambuc 
420f7cf2976SLionel Sambuc /*
421f7cf2976SLionel Sambuc  * Handler for the -b option.
422f7cf2976SLionel Sambuc  */
423f7cf2976SLionel Sambuc 	/*ARGSUSED*/
424f7cf2976SLionel Sambuc 	public void
opt_b(type,s)425f7cf2976SLionel Sambuc opt_b(type, s)
426f7cf2976SLionel Sambuc 	int type;
427f7cf2976SLionel Sambuc 	char *s;
428f7cf2976SLionel Sambuc {
429f7cf2976SLionel Sambuc 	switch (type)
430f7cf2976SLionel Sambuc 	{
431f7cf2976SLionel Sambuc 	case INIT:
432f7cf2976SLionel Sambuc 	case TOGGLE:
433f7cf2976SLionel Sambuc 		/*
434f7cf2976SLionel Sambuc 		 * Set the new number of buffers.
435f7cf2976SLionel Sambuc 		 */
436f7cf2976SLionel Sambuc 		ch_setbufspace(bufspace);
437f7cf2976SLionel Sambuc 		break;
438f7cf2976SLionel Sambuc 	case QUERY:
439f7cf2976SLionel Sambuc 		break;
440f7cf2976SLionel Sambuc 	}
441f7cf2976SLionel Sambuc }
442f7cf2976SLionel Sambuc 
443f7cf2976SLionel Sambuc /*
444f7cf2976SLionel Sambuc  * Handler for the -i option.
445f7cf2976SLionel Sambuc  */
446f7cf2976SLionel Sambuc 	/*ARGSUSED*/
447f7cf2976SLionel Sambuc 	public void
opt_i(type,s)448f7cf2976SLionel Sambuc opt_i(type, s)
449f7cf2976SLionel Sambuc 	int type;
450f7cf2976SLionel Sambuc 	char *s;
451f7cf2976SLionel Sambuc {
452f7cf2976SLionel Sambuc 	switch (type)
453f7cf2976SLionel Sambuc 	{
454f7cf2976SLionel Sambuc 	case TOGGLE:
455f7cf2976SLionel Sambuc 		chg_caseless();
456f7cf2976SLionel Sambuc 		break;
457f7cf2976SLionel Sambuc 	case QUERY:
458f7cf2976SLionel Sambuc 	case INIT:
459f7cf2976SLionel Sambuc 		break;
460f7cf2976SLionel Sambuc 	}
461f7cf2976SLionel Sambuc }
462f7cf2976SLionel Sambuc 
463f7cf2976SLionel Sambuc /*
464f7cf2976SLionel Sambuc  * Handler for the -V option.
465f7cf2976SLionel Sambuc  */
466f7cf2976SLionel Sambuc 	/*ARGSUSED*/
467f7cf2976SLionel Sambuc 	public void
opt__V(type,s)468f7cf2976SLionel Sambuc opt__V(type, s)
469f7cf2976SLionel Sambuc 	int type;
470f7cf2976SLionel Sambuc 	char *s;
471f7cf2976SLionel Sambuc {
472f7cf2976SLionel Sambuc 	switch (type)
473f7cf2976SLionel Sambuc 	{
474f7cf2976SLionel Sambuc 	case TOGGLE:
475f7cf2976SLionel Sambuc 	case QUERY:
476f7cf2976SLionel Sambuc 		dispversion();
477f7cf2976SLionel Sambuc 		break;
478f7cf2976SLionel Sambuc 	case INIT:
479f7cf2976SLionel Sambuc 		/*
480f7cf2976SLionel Sambuc 		 * Force output to stdout per GNU standard for --version output.
481f7cf2976SLionel Sambuc 		 */
482f7cf2976SLionel Sambuc 		any_display = 1;
483f7cf2976SLionel Sambuc 		putstr("less ");
484f7cf2976SLionel Sambuc 		putstr(version);
485*84d9c625SLionel Sambuc 		putstr(" (");
486*84d9c625SLionel Sambuc #if HAVE_GNU_REGEX
487*84d9c625SLionel Sambuc 		putstr("GNU ");
488*84d9c625SLionel Sambuc #endif
489*84d9c625SLionel Sambuc #if HAVE_POSIX_REGCOMP
490*84d9c625SLionel Sambuc 		putstr("POSIX ");
491*84d9c625SLionel Sambuc #endif
492*84d9c625SLionel Sambuc #if HAVE_PCRE
493*84d9c625SLionel Sambuc 		putstr("PCRE ");
494*84d9c625SLionel Sambuc #endif
495*84d9c625SLionel Sambuc #if HAVE_RE_COMP
496*84d9c625SLionel Sambuc 		putstr("BSD ");
497*84d9c625SLionel Sambuc #endif
498*84d9c625SLionel Sambuc #if HAVE_REGCMP
499*84d9c625SLionel Sambuc 		putstr("V8 ");
500*84d9c625SLionel Sambuc #endif
501*84d9c625SLionel Sambuc #if HAVE_V8_REGCOMP
502*84d9c625SLionel Sambuc 		putstr("Spencer V8 ");
503*84d9c625SLionel Sambuc #endif
504*84d9c625SLionel Sambuc #if !HAVE_GNU_REGEX && !HAVE_POSIX_REGCOMP && !HAVE_PCRE && !HAVE_RE_COMP && !HAVE_REGCMP && !HAVE_V8_REGCOMP
505*84d9c625SLionel Sambuc 		putstr("no ");
506*84d9c625SLionel Sambuc #endif
507*84d9c625SLionel Sambuc 		putstr("regular expressions)\n");
508*84d9c625SLionel Sambuc 		putstr("Copyright (C) 1984-2012 Mark Nudelman\n\n");
509f7cf2976SLionel Sambuc 		putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
510f7cf2976SLionel Sambuc 		putstr("For information about the terms of redistribution,\n");
511f7cf2976SLionel Sambuc 		putstr("see the file named README in the less distribution.\n");
512f7cf2976SLionel Sambuc 		putstr("Homepage: http://www.greenwoodsoftware.com/less\n");
513f7cf2976SLionel Sambuc 		quit(QUIT_OK);
514f7cf2976SLionel Sambuc 		break;
515f7cf2976SLionel Sambuc 	}
516f7cf2976SLionel Sambuc }
517f7cf2976SLionel Sambuc 
518f7cf2976SLionel Sambuc #if MSDOS_COMPILER
519f7cf2976SLionel Sambuc /*
520f7cf2976SLionel Sambuc  * Parse an MSDOS color descriptor.
521f7cf2976SLionel Sambuc  */
522f7cf2976SLionel Sambuc    	static void
colordesc(s,fg_color,bg_color)523f7cf2976SLionel Sambuc colordesc(s, fg_color, bg_color)
524f7cf2976SLionel Sambuc 	char *s;
525f7cf2976SLionel Sambuc 	int *fg_color;
526f7cf2976SLionel Sambuc 	int *bg_color;
527f7cf2976SLionel Sambuc {
528f7cf2976SLionel Sambuc 	int fg, bg;
529f7cf2976SLionel Sambuc 	int err;
530f7cf2976SLionel Sambuc 
531f7cf2976SLionel Sambuc 	fg = getnum(&s, "D", &err);
532f7cf2976SLionel Sambuc 	if (err)
533f7cf2976SLionel Sambuc 	{
534f7cf2976SLionel Sambuc 		error("Missing fg color in -D", NULL_PARG);
535f7cf2976SLionel Sambuc 		return;
536f7cf2976SLionel Sambuc 	}
537f7cf2976SLionel Sambuc 	if (*s != '.')
538f7cf2976SLionel Sambuc 		bg = nm_bg_color;
539f7cf2976SLionel Sambuc 	else
540f7cf2976SLionel Sambuc 	{
541f7cf2976SLionel Sambuc 		s++;
542f7cf2976SLionel Sambuc 		bg = getnum(&s, "D", &err);
543f7cf2976SLionel Sambuc 		if (err)
544f7cf2976SLionel Sambuc 		{
545f7cf2976SLionel Sambuc 			error("Missing bg color in -D", NULL_PARG);
546f7cf2976SLionel Sambuc 			return;
547f7cf2976SLionel Sambuc 		}
548f7cf2976SLionel Sambuc 	}
549f7cf2976SLionel Sambuc 	if (*s != '\0')
550f7cf2976SLionel Sambuc 		error("Extra characters at end of -D option", NULL_PARG);
551f7cf2976SLionel Sambuc 	*fg_color = fg;
552f7cf2976SLionel Sambuc 	*bg_color = bg;
553f7cf2976SLionel Sambuc }
554f7cf2976SLionel Sambuc 
555f7cf2976SLionel Sambuc /*
556f7cf2976SLionel Sambuc  * Handler for the -D option.
557f7cf2976SLionel Sambuc  */
558f7cf2976SLionel Sambuc 	/*ARGSUSED*/
559f7cf2976SLionel Sambuc 	public void
opt_D(type,s)560f7cf2976SLionel Sambuc opt_D(type, s)
561f7cf2976SLionel Sambuc 	int type;
562f7cf2976SLionel Sambuc 	char *s;
563f7cf2976SLionel Sambuc {
564f7cf2976SLionel Sambuc 	switch (type)
565f7cf2976SLionel Sambuc 	{
566f7cf2976SLionel Sambuc 	case INIT:
567f7cf2976SLionel Sambuc 	case TOGGLE:
568f7cf2976SLionel Sambuc 		switch (*s++)
569f7cf2976SLionel Sambuc 		{
570f7cf2976SLionel Sambuc 		case 'n':
571f7cf2976SLionel Sambuc 			colordesc(s, &nm_fg_color, &nm_bg_color);
572f7cf2976SLionel Sambuc 			break;
573f7cf2976SLionel Sambuc 		case 'd':
574f7cf2976SLionel Sambuc 			colordesc(s, &bo_fg_color, &bo_bg_color);
575f7cf2976SLionel Sambuc 			break;
576f7cf2976SLionel Sambuc 		case 'u':
577f7cf2976SLionel Sambuc 			colordesc(s, &ul_fg_color, &ul_bg_color);
578f7cf2976SLionel Sambuc 			break;
579f7cf2976SLionel Sambuc 		case 'k':
580f7cf2976SLionel Sambuc 			colordesc(s, &bl_fg_color, &bl_bg_color);
581f7cf2976SLionel Sambuc 			break;
582f7cf2976SLionel Sambuc 		case 's':
583f7cf2976SLionel Sambuc 			colordesc(s, &so_fg_color, &so_bg_color);
584f7cf2976SLionel Sambuc 			break;
585f7cf2976SLionel Sambuc 		default:
586f7cf2976SLionel Sambuc 			error("-D must be followed by n, d, u, k or s", NULL_PARG);
587f7cf2976SLionel Sambuc 			break;
588f7cf2976SLionel Sambuc 		}
589f7cf2976SLionel Sambuc 		if (type == TOGGLE)
590f7cf2976SLionel Sambuc 		{
591f7cf2976SLionel Sambuc 			at_enter(AT_STANDOUT);
592f7cf2976SLionel Sambuc 			at_exit();
593f7cf2976SLionel Sambuc 		}
594f7cf2976SLionel Sambuc 		break;
595f7cf2976SLionel Sambuc 	case QUERY:
596f7cf2976SLionel Sambuc 		break;
597f7cf2976SLionel Sambuc 	}
598f7cf2976SLionel Sambuc }
599f7cf2976SLionel Sambuc #endif
600f7cf2976SLionel Sambuc 
601f7cf2976SLionel Sambuc /*
602f7cf2976SLionel Sambuc  * Handler for the -x option.
603f7cf2976SLionel Sambuc  */
604f7cf2976SLionel Sambuc 	public void
opt_x(type,s)605f7cf2976SLionel Sambuc opt_x(type, s)
606f7cf2976SLionel Sambuc 	int type;
607f7cf2976SLionel Sambuc 	register char *s;
608f7cf2976SLionel Sambuc {
609f7cf2976SLionel Sambuc 	extern int tabstops[];
610f7cf2976SLionel Sambuc 	extern int ntabstops;
611f7cf2976SLionel Sambuc 	extern int tabdefault;
612f7cf2976SLionel Sambuc 	char msg[60+(4*TABSTOP_MAX)];
613f7cf2976SLionel Sambuc 	int i;
614f7cf2976SLionel Sambuc 	PARG p;
615f7cf2976SLionel Sambuc 
616f7cf2976SLionel Sambuc 	switch (type)
617f7cf2976SLionel Sambuc 	{
618f7cf2976SLionel Sambuc 	case INIT:
619f7cf2976SLionel Sambuc 	case TOGGLE:
620f7cf2976SLionel Sambuc 		/* Start at 1 because tabstops[0] is always zero. */
621f7cf2976SLionel Sambuc 		for (i = 1;  i < TABSTOP_MAX;  )
622f7cf2976SLionel Sambuc 		{
623f7cf2976SLionel Sambuc 			int n = 0;
624f7cf2976SLionel Sambuc 			s = skipsp(s);
625f7cf2976SLionel Sambuc 			while (*s >= '0' && *s <= '9')
626f7cf2976SLionel Sambuc 				n = (10 * n) + (*s++ - '0');
627f7cf2976SLionel Sambuc 			if (n > tabstops[i-1])
628f7cf2976SLionel Sambuc 				tabstops[i++] = n;
629f7cf2976SLionel Sambuc 			s = skipsp(s);
630f7cf2976SLionel Sambuc 			if (*s++ != ',')
631f7cf2976SLionel Sambuc 				break;
632f7cf2976SLionel Sambuc 		}
633f7cf2976SLionel Sambuc 		if (i < 2)
634f7cf2976SLionel Sambuc 			return;
635f7cf2976SLionel Sambuc 		ntabstops = i;
636f7cf2976SLionel Sambuc 		tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
637f7cf2976SLionel Sambuc 		break;
638f7cf2976SLionel Sambuc 	case QUERY:
639f7cf2976SLionel Sambuc 		strcpy(msg, "Tab stops ");
640f7cf2976SLionel Sambuc 		if (ntabstops > 2)
641f7cf2976SLionel Sambuc 		{
642f7cf2976SLionel Sambuc 			for (i = 1;  i < ntabstops;  i++)
643f7cf2976SLionel Sambuc 			{
644f7cf2976SLionel Sambuc 				if (i > 1)
645f7cf2976SLionel Sambuc 					strcat(msg, ",");
646f7cf2976SLionel Sambuc 				sprintf(msg+strlen(msg), "%d", tabstops[i]);
647f7cf2976SLionel Sambuc 			}
648f7cf2976SLionel Sambuc 			sprintf(msg+strlen(msg), " and then ");
649f7cf2976SLionel Sambuc 		}
650f7cf2976SLionel Sambuc 		sprintf(msg+strlen(msg), "every %d spaces",
651f7cf2976SLionel Sambuc 			tabdefault);
652f7cf2976SLionel Sambuc 		p.p_string = msg;
653f7cf2976SLionel Sambuc 		error("%s", &p);
654f7cf2976SLionel Sambuc 		break;
655f7cf2976SLionel Sambuc 	}
656f7cf2976SLionel Sambuc }
657f7cf2976SLionel Sambuc 
658f7cf2976SLionel Sambuc 
659f7cf2976SLionel Sambuc /*
660f7cf2976SLionel Sambuc  * Handler for the -" option.
661f7cf2976SLionel Sambuc  */
662f7cf2976SLionel Sambuc 	public void
opt_quote(type,s)663f7cf2976SLionel Sambuc opt_quote(type, s)
664f7cf2976SLionel Sambuc 	int type;
665f7cf2976SLionel Sambuc 	register char *s;
666f7cf2976SLionel Sambuc {
667f7cf2976SLionel Sambuc 	char buf[3];
668f7cf2976SLionel Sambuc 	PARG parg;
669f7cf2976SLionel Sambuc 
670f7cf2976SLionel Sambuc 	switch (type)
671f7cf2976SLionel Sambuc 	{
672f7cf2976SLionel Sambuc 	case INIT:
673f7cf2976SLionel Sambuc 	case TOGGLE:
674f7cf2976SLionel Sambuc 		if (s[0] == '\0')
675f7cf2976SLionel Sambuc 		{
676f7cf2976SLionel Sambuc 			openquote = closequote = '\0';
677f7cf2976SLionel Sambuc 			break;
678f7cf2976SLionel Sambuc 		}
679f7cf2976SLionel Sambuc 		if (s[1] != '\0' && s[2] != '\0')
680f7cf2976SLionel Sambuc 		{
681f7cf2976SLionel Sambuc 			error("-\" must be followed by 1 or 2 chars", NULL_PARG);
682f7cf2976SLionel Sambuc 			return;
683f7cf2976SLionel Sambuc 		}
684f7cf2976SLionel Sambuc 		openquote = s[0];
685f7cf2976SLionel Sambuc 		if (s[1] == '\0')
686f7cf2976SLionel Sambuc 			closequote = openquote;
687f7cf2976SLionel Sambuc 		else
688f7cf2976SLionel Sambuc 			closequote = s[1];
689f7cf2976SLionel Sambuc 		break;
690f7cf2976SLionel Sambuc 	case QUERY:
691f7cf2976SLionel Sambuc 		buf[0] = openquote;
692f7cf2976SLionel Sambuc 		buf[1] = closequote;
693f7cf2976SLionel Sambuc 		buf[2] = '\0';
694f7cf2976SLionel Sambuc 		parg.p_string = buf;
695f7cf2976SLionel Sambuc 		error("quotes %s", &parg);
696f7cf2976SLionel Sambuc 		break;
697f7cf2976SLionel Sambuc 	}
698f7cf2976SLionel Sambuc }
699f7cf2976SLionel Sambuc 
700f7cf2976SLionel Sambuc /*
701f7cf2976SLionel Sambuc  * "-?" means display a help message.
702f7cf2976SLionel Sambuc  * If from the command line, exit immediately.
703f7cf2976SLionel Sambuc  */
704f7cf2976SLionel Sambuc 	/*ARGSUSED*/
705f7cf2976SLionel Sambuc 	public void
opt_query(type,s)706f7cf2976SLionel Sambuc opt_query(type, s)
707f7cf2976SLionel Sambuc 	int type;
708f7cf2976SLionel Sambuc 	char *s;
709f7cf2976SLionel Sambuc {
710f7cf2976SLionel Sambuc 	switch (type)
711f7cf2976SLionel Sambuc 	{
712f7cf2976SLionel Sambuc 	case QUERY:
713f7cf2976SLionel Sambuc 	case TOGGLE:
714f7cf2976SLionel Sambuc 		error("Use \"h\" for help", NULL_PARG);
715f7cf2976SLionel Sambuc 		break;
716f7cf2976SLionel Sambuc 	case INIT:
717f7cf2976SLionel Sambuc 		dohelp = 1;
718f7cf2976SLionel Sambuc 	}
719f7cf2976SLionel Sambuc }
720f7cf2976SLionel Sambuc 
721f7cf2976SLionel Sambuc /*
722f7cf2976SLionel Sambuc  * Get the "screen window" size.
723f7cf2976SLionel Sambuc  */
724f7cf2976SLionel Sambuc 	public int
get_swindow()725f7cf2976SLionel Sambuc get_swindow()
726f7cf2976SLionel Sambuc {
727f7cf2976SLionel Sambuc 	if (swindow > 0)
728f7cf2976SLionel Sambuc 		return (swindow);
729f7cf2976SLionel Sambuc 	return (sc_height + swindow);
730f7cf2976SLionel Sambuc }
731f7cf2976SLionel Sambuc 
732