1238730Sdelphij/*
2330571Sdelphij * Copyright (C) 1984-2017  Mark Nudelman
3238730Sdelphij *
4238730Sdelphij * You may distribute under the terms of either the GNU General Public
5238730Sdelphij * License or the Less License, as specified in the README file.
6238730Sdelphij *
7238730Sdelphij * For more information, see the README file.
8238730Sdelphij */
960786Sps
1060786Sps
1160786Sps/*
1260786Sps * Handling functions for command line options.
1360786Sps *
1460786Sps * Most options are handled by the generic code in option.c.
1560786Sps * But all string options, and a few non-string options, require
1660786Sps * special handling specific to the particular option.
1760786Sps * This special processing is done by the "handling functions" in this file.
1860786Sps *
1960786Sps * Each handling function is passed a "type" and, if it is a string
2060786Sps * option, the string which should be "assigned" to the option.
2160786Sps * The type may be one of:
2260786Sps *	INIT	The option is being initialized from the command line.
2360786Sps *	TOGGLE	The option is being changed from within the program.
2460786Sps *	QUERY	The setting of the option is merely being queried.
2560786Sps */
2660786Sps
2760786Sps#include "less.h"
2860786Sps#include "option.h"
2960786Sps
3060786Spsextern int nbufs;
31128345Stjrextern int bufspace;
3260786Spsextern int pr_type;
3360786Spsextern int plusoption;
3460786Spsextern int swindow;
35195941Sdelphijextern int sc_width;
3660786Spsextern int sc_height;
3760786Spsextern int secure;
3860786Spsextern int dohelp;
3960786Spsextern int any_display;
4060786Spsextern char openquote;
4160786Spsextern char closequote;
4260786Spsextern char *prproto[];
4360786Spsextern char *eqproto;
4460786Spsextern char *hproto;
4589019Spsextern char *wproto;
46294286Sdelphijextern char *every_first_cmd;
4760786Spsextern IFILE curr_ifile;
4860786Spsextern char version[];
49170964Sdelphijextern int jump_sline;
50330571Sdelphijextern long jump_sline_fraction;
51195941Sdelphijextern int shift_count;
52330571Sdelphijextern long shift_count_fraction;
53330571Sdelphijextern LWCHAR rscroll_char;
54330571Sdelphijextern int rscroll_attr;
55170964Sdelphijextern int less_is_more;
5660786Sps#if LOGFILE
5760786Spsextern char *namelogfile;
5860786Spsextern int force_logfile;
5960786Spsextern int logfile;
6060786Sps#endif
6160786Sps#if TAGS
6260786Spspublic char *tagoption = NULL;
6360786Spsextern char *tags;
64294286Sdelphijextern char ztags[];
6560786Sps#endif
6660786Sps#if MSDOS_COMPILER
6760786Spsextern int nm_fg_color, nm_bg_color;
6860786Spsextern int bo_fg_color, bo_bg_color;
6960786Spsextern int ul_fg_color, ul_bg_color;
7060786Spsextern int so_fg_color, so_bg_color;
7160786Spsextern int bl_fg_color, bl_bg_color;
72330571Sdelphijextern int sgr_mode;
73330571Sdelphij#if MSDOS_COMPILER==WIN32C
74330571Sdelphij#ifndef COMMON_LVB_UNDERSCORE
75330571Sdelphij#define COMMON_LVB_UNDERSCORE 0x8000
7660786Sps#endif
77330571Sdelphij#endif
78330571Sdelphij#endif
7960786Sps
8060786Sps
8160786Sps#if LOGFILE
8260786Sps/*
8360786Sps * Handler for -o option.
8460786Sps */
8560786Sps	public void
8660786Spsopt_o(type, s)
8760786Sps	int type;
8860786Sps	char *s;
8960786Sps{
9060786Sps	PARG parg;
91330571Sdelphij	char *filename;
9260786Sps
9360786Sps	if (secure)
9460786Sps	{
9560786Sps		error("log file support is not available", NULL_PARG);
9660786Sps		return;
9760786Sps	}
9860786Sps	switch (type)
9960786Sps	{
10060786Sps	case INIT:
101294286Sdelphij		namelogfile = save(s);
10260786Sps		break;
10360786Sps	case TOGGLE:
10460786Sps		if (ch_getflags() & CH_CANSEEK)
10560786Sps		{
10660786Sps			error("Input is not a pipe", NULL_PARG);
10760786Sps			return;
10860786Sps		}
10960786Sps		if (logfile >= 0)
11060786Sps		{
11160786Sps			error("Log file is already in use", NULL_PARG);
11260786Sps			return;
11360786Sps		}
11460786Sps		s = skipsp(s);
115294286Sdelphij		if (namelogfile != NULL)
116294286Sdelphij			free(namelogfile);
117330571Sdelphij		filename = lglob(s);
118330571Sdelphij		namelogfile = shell_unquote(filename);
119330571Sdelphij		free(filename);
12060786Sps		use_logfile(namelogfile);
12160786Sps		sync_logfile();
12260786Sps		break;
12360786Sps	case QUERY:
12460786Sps		if (logfile < 0)
12560786Sps			error("No log file", NULL_PARG);
12660786Sps		else
12760786Sps		{
128128345Stjr			parg.p_string = namelogfile;
12960786Sps			error("Log file \"%s\"", &parg);
13060786Sps		}
13160786Sps		break;
13260786Sps	}
13360786Sps}
13460786Sps
13560786Sps/*
13660786Sps * Handler for -O option.
13760786Sps */
13860786Sps	public void
13960786Spsopt__O(type, s)
14060786Sps	int type;
14160786Sps	char *s;
14260786Sps{
14360786Sps	force_logfile = TRUE;
14460786Sps	opt_o(type, s);
14560786Sps}
14660786Sps#endif
14760786Sps
14860786Sps/*
149170256Sdelphij * Handlers for -j option.
150170256Sdelphij */
151170256Sdelphij	public void
152170256Sdelphijopt_j(type, s)
153170256Sdelphij	int type;
154170256Sdelphij	char *s;
155170256Sdelphij{
156170256Sdelphij	PARG parg;
157170256Sdelphij	char buf[16];
158170256Sdelphij	int len;
159170256Sdelphij	int err;
160170256Sdelphij
161170256Sdelphij	switch (type)
162170256Sdelphij	{
163170256Sdelphij	case INIT:
164170256Sdelphij	case TOGGLE:
165170256Sdelphij		if (*s == '.')
166170256Sdelphij		{
167170256Sdelphij			s++;
168170256Sdelphij			jump_sline_fraction = getfraction(&s, "j", &err);
169170256Sdelphij			if (err)
170170256Sdelphij				error("Invalid line fraction", NULL_PARG);
171170256Sdelphij			else
172170256Sdelphij				calc_jump_sline();
173170256Sdelphij		} else
174170256Sdelphij		{
175170256Sdelphij			int sline = getnum(&s, "j", &err);
176170256Sdelphij			if (err)
177170256Sdelphij				error("Invalid line number", NULL_PARG);
178170256Sdelphij			else
179170256Sdelphij			{
180170256Sdelphij				jump_sline = sline;
181170256Sdelphij				jump_sline_fraction = -1;
182170256Sdelphij			}
183170256Sdelphij		}
184170256Sdelphij		break;
185170256Sdelphij	case QUERY:
186170256Sdelphij		if (jump_sline_fraction < 0)
187170256Sdelphij		{
188170256Sdelphij			parg.p_int =  jump_sline;
189170256Sdelphij			error("Position target at screen line %d", &parg);
190170256Sdelphij		} else
191170256Sdelphij		{
192170256Sdelphij
193330571Sdelphij			sprintf(buf, ".%06ld", jump_sline_fraction);
194294286Sdelphij			len = (int) strlen(buf);
195170256Sdelphij			while (len > 2 && buf[len-1] == '0')
196170256Sdelphij				len--;
197170256Sdelphij			buf[len] = '\0';
198170256Sdelphij			parg.p_string = buf;
199170256Sdelphij			error("Position target at screen position %s", &parg);
200170256Sdelphij		}
201170256Sdelphij		break;
202170256Sdelphij	}
203170256Sdelphij}
204170256Sdelphij
205170256Sdelphij	public void
206170256Sdelphijcalc_jump_sline()
207170256Sdelphij{
208170256Sdelphij	if (jump_sline_fraction < 0)
209170256Sdelphij		return;
210170256Sdelphij	jump_sline = sc_height * jump_sline_fraction / NUM_FRAC_DENOM;
211170256Sdelphij}
212170256Sdelphij
213195941Sdelphij/*
214195941Sdelphij * Handlers for -# option.
215195941Sdelphij */
216195941Sdelphij	public void
217195941Sdelphijopt_shift(type, s)
218195941Sdelphij	int type;
219195941Sdelphij	char *s;
220195941Sdelphij{
221195941Sdelphij	PARG parg;
222195941Sdelphij	char buf[16];
223195941Sdelphij	int len;
224195941Sdelphij	int err;
225195941Sdelphij
226195941Sdelphij	switch (type)
227195941Sdelphij	{
228195941Sdelphij	case INIT:
229195941Sdelphij	case TOGGLE:
230195941Sdelphij		if (*s == '.')
231195941Sdelphij		{
232195941Sdelphij			s++;
233195941Sdelphij			shift_count_fraction = getfraction(&s, "#", &err);
234195941Sdelphij			if (err)
235195941Sdelphij				error("Invalid column fraction", NULL_PARG);
236195941Sdelphij			else
237195941Sdelphij				calc_shift_count();
238195941Sdelphij		} else
239195941Sdelphij		{
240195941Sdelphij			int hs = getnum(&s, "#", &err);
241195941Sdelphij			if (err)
242195941Sdelphij				error("Invalid column number", NULL_PARG);
243195941Sdelphij			else
244195941Sdelphij			{
245195941Sdelphij				shift_count = hs;
246195941Sdelphij				shift_count_fraction = -1;
247195941Sdelphij			}
248195941Sdelphij		}
249195941Sdelphij		break;
250195941Sdelphij	case QUERY:
251195941Sdelphij		if (shift_count_fraction < 0)
252195941Sdelphij		{
253195941Sdelphij			parg.p_int = shift_count;
254195941Sdelphij			error("Horizontal shift %d columns", &parg);
255195941Sdelphij		} else
256195941Sdelphij		{
257195941Sdelphij
258330571Sdelphij			sprintf(buf, ".%06ld", shift_count_fraction);
259294286Sdelphij			len = (int) strlen(buf);
260195941Sdelphij			while (len > 2 && buf[len-1] == '0')
261195941Sdelphij				len--;
262195941Sdelphij			buf[len] = '\0';
263195941Sdelphij			parg.p_string = buf;
264195941Sdelphij			error("Horizontal shift %s of screen width", &parg);
265195941Sdelphij		}
266195941Sdelphij		break;
267195941Sdelphij	}
268195941Sdelphij}
269195941Sdelphij	public void
270195941Sdelphijcalc_shift_count()
271195941Sdelphij{
272195941Sdelphij	if (shift_count_fraction < 0)
273195941Sdelphij		return;
274195941Sdelphij	shift_count = sc_width * shift_count_fraction / NUM_FRAC_DENOM;
275195941Sdelphij}
276195941Sdelphij
27760786Sps#if USERFILE
27860786Sps	public void
27960786Spsopt_k(type, s)
28060786Sps	int type;
28160786Sps	char *s;
28260786Sps{
28360786Sps	PARG parg;
28460786Sps
28560786Sps	switch (type)
28660786Sps	{
28760786Sps	case INIT:
28860786Sps		if (lesskey(s, 0))
28960786Sps		{
290128345Stjr			parg.p_string = s;
29160786Sps			error("Cannot use lesskey file \"%s\"", &parg);
29260786Sps		}
29360786Sps		break;
29460786Sps	}
29560786Sps}
29660786Sps#endif
29760786Sps
29860786Sps#if TAGS
29960786Sps/*
30060786Sps * Handler for -t option.
30160786Sps */
30260786Sps	public void
30360786Spsopt_t(type, s)
30460786Sps	int type;
30560786Sps	char *s;
30660786Sps{
30760786Sps	IFILE save_ifile;
30860786Sps	POSITION pos;
30960786Sps
31060786Sps	switch (type)
31160786Sps	{
31260786Sps	case INIT:
313294286Sdelphij		tagoption = save(s);
31460786Sps		/* Do the rest in main() */
31560786Sps		break;
31660786Sps	case TOGGLE:
31760786Sps		if (secure)
31860786Sps		{
31960786Sps			error("tags support is not available", NULL_PARG);
32060786Sps			break;
32160786Sps		}
32260786Sps		findtag(skipsp(s));
32360786Sps		save_ifile = save_curr_ifile();
324161475Sdelphij		/*
325161475Sdelphij		 * Try to open the file containing the tag
326161475Sdelphij		 * and search for the tag in that file.
327161475Sdelphij		 */
328161475Sdelphij		if (edit_tagfile() || (pos = tagsearch()) == NULL_POSITION)
32960786Sps		{
330161475Sdelphij			/* Failed: reopen the old file. */
33160786Sps			reedit_ifile(save_ifile);
33260786Sps			break;
33360786Sps		}
33460786Sps		unsave_ifile(save_ifile);
33560786Sps		jump_loc(pos, jump_sline);
33660786Sps		break;
33760786Sps	}
33860786Sps}
33960786Sps
34060786Sps/*
34160786Sps * Handler for -T option.
34260786Sps */
34360786Sps	public void
34460786Spsopt__T(type, s)
34560786Sps	int type;
34660786Sps	char *s;
34760786Sps{
34860786Sps	PARG parg;
349330571Sdelphij	char *filename;
35060786Sps
35160786Sps	switch (type)
35260786Sps	{
35360786Sps	case INIT:
354294286Sdelphij		tags = save(s);
35560786Sps		break;
35660786Sps	case TOGGLE:
35760786Sps		s = skipsp(s);
358294286Sdelphij		if (tags != NULL && tags != ztags)
359294286Sdelphij			free(tags);
360330571Sdelphij		filename = lglob(s);
361330571Sdelphij		tags = shell_unquote(filename);
362330571Sdelphij		free(filename);
36360786Sps		break;
36460786Sps	case QUERY:
365128345Stjr		parg.p_string = tags;
36660786Sps		error("Tags file \"%s\"", &parg);
36760786Sps		break;
36860786Sps	}
36960786Sps}
37060786Sps#endif
37160786Sps
37260786Sps/*
37360786Sps * Handler for -p option.
37460786Sps */
37560786Sps	public void
37660786Spsopt_p(type, s)
37760786Sps	int type;
378330571Sdelphij	char *s;
37960786Sps{
38060786Sps	switch (type)
38160786Sps	{
38260786Sps	case INIT:
38360786Sps		/*
384294286Sdelphij		 * Unget a command for the specified string.
38560786Sps		 */
386294286Sdelphij		if (less_is_more)
387294286Sdelphij		{
388294286Sdelphij			/*
389294286Sdelphij			 * In "more" mode, the -p argument is a command,
390294286Sdelphij			 * not a search string, so we don't need a slash.
391294286Sdelphij			 */
392294286Sdelphij			every_first_cmd = save(s);
393294286Sdelphij		} else
394294286Sdelphij		{
395294286Sdelphij			plusoption = TRUE;
396294286Sdelphij			ungetcc(CHAR_END_COMMAND);
397294286Sdelphij			ungetsc(s);
398294286Sdelphij			 /*
399294286Sdelphij			  * {{ This won't work if the "/" command is
400294286Sdelphij			  *    changed or invalidated by a .lesskey file. }}
401294286Sdelphij			  */
402161475Sdelphij			ungetsc("/");
403294286Sdelphij		}
40460786Sps		break;
40560786Sps	}
40660786Sps}
40760786Sps
40860786Sps/*
40960786Sps * Handler for -P option.
41060786Sps */
41160786Sps	public void
41260786Spsopt__P(type, s)
41360786Sps	int type;
414330571Sdelphij	char *s;
41560786Sps{
416330571Sdelphij	char **proto;
41760786Sps	PARG parg;
41860786Sps
41960786Sps	switch (type)
42060786Sps	{
42160786Sps	case INIT:
42260786Sps	case TOGGLE:
42360786Sps		/*
42460786Sps		 * Figure out which prototype string should be changed.
42560786Sps		 */
42660786Sps		switch (*s)
42760786Sps		{
42860786Sps		case 's':  proto = &prproto[PR_SHORT];	s++;	break;
42960786Sps		case 'm':  proto = &prproto[PR_MEDIUM];	s++;	break;
43060786Sps		case 'M':  proto = &prproto[PR_LONG];	s++;	break;
43160786Sps		case '=':  proto = &eqproto;		s++;	break;
43260786Sps		case 'h':  proto = &hproto;		s++;	break;
43389019Sps		case 'w':  proto = &wproto;		s++;	break;
43460786Sps		default:   proto = &prproto[PR_SHORT];		break;
43560786Sps		}
43660786Sps		free(*proto);
43760786Sps		*proto = save(s);
43860786Sps		break;
43960786Sps	case QUERY:
44060786Sps		parg.p_string = prproto[pr_type];
44160786Sps		error("%s", &parg);
44260786Sps		break;
44360786Sps	}
44460786Sps}
44560786Sps
44660786Sps/*
44760786Sps * Handler for the -b option.
44860786Sps */
44960786Sps	/*ARGSUSED*/
45060786Sps	public void
45160786Spsopt_b(type, s)
45260786Sps	int type;
45360786Sps	char *s;
45460786Sps{
45560786Sps	switch (type)
45660786Sps	{
457128345Stjr	case INIT:
45860786Sps	case TOGGLE:
45960786Sps		/*
460128345Stjr		 * Set the new number of buffers.
46160786Sps		 */
462128345Stjr		ch_setbufspace(bufspace);
46360786Sps		break;
464128345Stjr	case QUERY:
46560786Sps		break;
46660786Sps	}
46760786Sps}
46860786Sps
46960786Sps/*
47060786Sps * Handler for the -i option.
47160786Sps */
47260786Sps	/*ARGSUSED*/
47360786Sps	public void
47460786Spsopt_i(type, s)
47560786Sps	int type;
47660786Sps	char *s;
47760786Sps{
47860786Sps	switch (type)
47960786Sps	{
48060786Sps	case TOGGLE:
48160786Sps		chg_caseless();
48260786Sps		break;
48360786Sps	case QUERY:
48460786Sps	case INIT:
48560786Sps		break;
48660786Sps	}
48760786Sps}
48860786Sps
48960786Sps/*
49060786Sps * Handler for the -V option.
49160786Sps */
49260786Sps	/*ARGSUSED*/
49360786Sps	public void
49460786Spsopt__V(type, s)
49560786Sps	int type;
49660786Sps	char *s;
49760786Sps{
49860786Sps	switch (type)
49960786Sps	{
50060786Sps	case TOGGLE:
50160786Sps	case QUERY:
50260786Sps		dispversion();
50360786Sps		break;
50460786Sps	case INIT:
50560786Sps		/*
50660786Sps		 * Force output to stdout per GNU standard for --version output.
50760786Sps		 */
50860786Sps		any_display = 1;
50960786Sps		putstr("less ");
51060786Sps		putstr(version);
511237613Sdelphij		putstr(" (");
512237613Sdelphij#if HAVE_GNU_REGEX
513237613Sdelphij		putstr("GNU ");
514237613Sdelphij#endif
515237613Sdelphij#if HAVE_POSIX_REGCOMP
516237613Sdelphij		putstr("POSIX ");
517237613Sdelphij#endif
518237613Sdelphij#if HAVE_PCRE
519237613Sdelphij		putstr("PCRE ");
520237613Sdelphij#endif
521237613Sdelphij#if HAVE_RE_COMP
522237613Sdelphij		putstr("BSD ");
523237613Sdelphij#endif
524237613Sdelphij#if HAVE_REGCMP
525237613Sdelphij		putstr("V8 ");
526237613Sdelphij#endif
527237613Sdelphij#if HAVE_V8_REGCOMP
528237613Sdelphij		putstr("Spencer V8 ");
529237613Sdelphij#endif
530237613Sdelphij#if !HAVE_GNU_REGEX && !HAVE_POSIX_REGCOMP && !HAVE_PCRE && !HAVE_RE_COMP && !HAVE_REGCMP && !HAVE_V8_REGCOMP
531237613Sdelphij		putstr("no ");
532237613Sdelphij#endif
533237613Sdelphij		putstr("regular expressions)\n");
534330571Sdelphij		putstr("Copyright (C) 1984-2017  Mark Nudelman\n\n");
53560786Sps		putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
53660786Sps		putstr("For information about the terms of redistribution,\n");
53760786Sps		putstr("see the file named README in the less distribution.\n");
53889019Sps		putstr("Homepage: http://www.greenwoodsoftware.com/less\n");
53960786Sps		quit(QUIT_OK);
54060786Sps		break;
54160786Sps	}
54260786Sps}
54360786Sps
54460786Sps#if MSDOS_COMPILER
54560786Sps/*
54660786Sps * Parse an MSDOS color descriptor.
54760786Sps */
54860786Sps   	static void
54960786Spscolordesc(s, fg_color, bg_color)
55060786Sps	char *s;
55160786Sps	int *fg_color;
55260786Sps	int *bg_color;
55360786Sps{
55460786Sps	int fg, bg;
55560786Sps	int err;
556330571Sdelphij#if MSDOS_COMPILER==WIN32C
557330571Sdelphij	int ul = 0;
558330571Sdelphij
559330571Sdelphij	if (*s == 'u')
560330571Sdelphij	{
561330571Sdelphij		ul = COMMON_LVB_UNDERSCORE;
562330571Sdelphij		++s;
563330571Sdelphij	}
564330571Sdelphij#endif
565128345Stjr	fg = getnum(&s, "D", &err);
56660786Sps	if (err)
56760786Sps	{
568330571Sdelphij#if MSDOS_COMPILER==WIN32C
569330571Sdelphij		if (ul)
570330571Sdelphij			fg = nm_fg_color;
571330571Sdelphij		else
572330571Sdelphij#endif
573330571Sdelphij		{
574330571Sdelphij			error("Missing fg color in -D", NULL_PARG);
575330571Sdelphij			return;
576330571Sdelphij		}
57760786Sps	}
57860786Sps	if (*s != '.')
579191930Sdelphij		bg = nm_bg_color;
58060786Sps	else
58160786Sps	{
58260786Sps		s++;
583128345Stjr		bg = getnum(&s, "D", &err);
58460786Sps		if (err)
58560786Sps		{
586191930Sdelphij			error("Missing bg color in -D", NULL_PARG);
58760786Sps			return;
58860786Sps		}
58960786Sps	}
590330571Sdelphij#if MSDOS_COMPILER==WIN32C
591330571Sdelphij	if (*s == 'u')
592330571Sdelphij	{
593330571Sdelphij		ul = COMMON_LVB_UNDERSCORE;
594330571Sdelphij		++s;
595330571Sdelphij	}
596330571Sdelphij	fg |= ul;
597330571Sdelphij#endif
59860786Sps	if (*s != '\0')
59960786Sps		error("Extra characters at end of -D option", NULL_PARG);
60060786Sps	*fg_color = fg;
60160786Sps	*bg_color = bg;
60260786Sps}
60360786Sps
60460786Sps/*
60560786Sps * Handler for the -D option.
60660786Sps */
60760786Sps	/*ARGSUSED*/
60860786Sps	public void
60960786Spsopt_D(type, s)
61060786Sps	int type;
61160786Sps	char *s;
61260786Sps{
613330571Sdelphij	PARG p;
614330571Sdelphij
61560786Sps	switch (type)
61660786Sps	{
61760786Sps	case INIT:
61860786Sps	case TOGGLE:
61960786Sps		switch (*s++)
62060786Sps		{
62160786Sps		case 'n':
62260786Sps			colordesc(s, &nm_fg_color, &nm_bg_color);
62360786Sps			break;
62460786Sps		case 'd':
62560786Sps			colordesc(s, &bo_fg_color, &bo_bg_color);
62660786Sps			break;
62760786Sps		case 'u':
62860786Sps			colordesc(s, &ul_fg_color, &ul_bg_color);
62960786Sps			break;
63060786Sps		case 'k':
63160786Sps			colordesc(s, &bl_fg_color, &bl_bg_color);
63260786Sps			break;
63360786Sps		case 's':
63460786Sps			colordesc(s, &so_fg_color, &so_bg_color);
63560786Sps			break;
636330571Sdelphij		case 'a':
637330571Sdelphij			sgr_mode = !sgr_mode;
638330571Sdelphij			break;
63960786Sps		default:
640330571Sdelphij			error("-D must be followed by n, d, u, k, s or a", NULL_PARG);
64160786Sps			break;
64260786Sps		}
64360786Sps		if (type == TOGGLE)
64460786Sps		{
645161475Sdelphij			at_enter(AT_STANDOUT);
646161475Sdelphij			at_exit();
64760786Sps		}
64860786Sps		break;
64960786Sps	case QUERY:
650330571Sdelphij		p.p_string = (sgr_mode) ? "on" : "off";
651330571Sdelphij		error("SGR mode is %s", &p);
65260786Sps		break;
65360786Sps	}
65460786Sps}
65560786Sps#endif
65660786Sps
65760786Sps/*
65889019Sps * Handler for the -x option.
65989019Sps */
66089019Sps	public void
66189019Spsopt_x(type, s)
66289019Sps	int type;
663330571Sdelphij	char *s;
66489019Sps{
66589019Sps	extern int tabstops[];
66689019Sps	extern int ntabstops;
66789019Sps	extern int tabdefault;
66889019Sps	char msg[60+(4*TABSTOP_MAX)];
66989019Sps	int i;
67089019Sps	PARG p;
67189019Sps
67289019Sps	switch (type)
67389019Sps	{
67489019Sps	case INIT:
67589019Sps	case TOGGLE:
67689019Sps		/* Start at 1 because tabstops[0] is always zero. */
67789019Sps		for (i = 1;  i < TABSTOP_MAX;  )
67889019Sps		{
67989019Sps			int n = 0;
680128345Stjr			s = skipsp(s);
68189019Sps			while (*s >= '0' && *s <= '9')
68289019Sps				n = (10 * n) + (*s++ - '0');
68389019Sps			if (n > tabstops[i-1])
68489019Sps				tabstops[i++] = n;
685128345Stjr			s = skipsp(s);
68689019Sps			if (*s++ != ',')
68789019Sps				break;
68889019Sps		}
68989019Sps		if (i < 2)
69089019Sps			return;
69189019Sps		ntabstops = i;
69289019Sps		tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
69389019Sps		break;
69489019Sps	case QUERY:
69589019Sps		strcpy(msg, "Tab stops ");
69689019Sps		if (ntabstops > 2)
69789019Sps		{
69889019Sps			for (i = 1;  i < ntabstops;  i++)
69989019Sps			{
70089019Sps				if (i > 1)
70189019Sps					strcat(msg, ",");
70289019Sps				sprintf(msg+strlen(msg), "%d", tabstops[i]);
70389019Sps			}
70489019Sps			sprintf(msg+strlen(msg), " and then ");
70589019Sps		}
70689019Sps		sprintf(msg+strlen(msg), "every %d spaces",
70789019Sps			tabdefault);
70889019Sps		p.p_string = msg;
70989019Sps		error("%s", &p);
71089019Sps		break;
71189019Sps	}
71289019Sps}
71389019Sps
71489019Sps
71589019Sps/*
71660786Sps * Handler for the -" option.
71760786Sps */
71860786Sps	public void
71960786Spsopt_quote(type, s)
72060786Sps	int type;
721330571Sdelphij	char *s;
72260786Sps{
72360786Sps	char buf[3];
72460786Sps	PARG parg;
72560786Sps
72660786Sps	switch (type)
72760786Sps	{
72860786Sps	case INIT:
72960786Sps	case TOGGLE:
730128345Stjr		if (s[0] == '\0')
731128345Stjr		{
732128345Stjr			openquote = closequote = '\0';
733128345Stjr			break;
734128345Stjr		}
73560786Sps		if (s[1] != '\0' && s[2] != '\0')
73660786Sps		{
73760786Sps			error("-\" must be followed by 1 or 2 chars", NULL_PARG);
73860786Sps			return;
73960786Sps		}
74060786Sps		openquote = s[0];
74160786Sps		if (s[1] == '\0')
74260786Sps			closequote = openquote;
74360786Sps		else
74460786Sps			closequote = s[1];
74560786Sps		break;
74660786Sps	case QUERY:
74760786Sps		buf[0] = openquote;
74860786Sps		buf[1] = closequote;
74960786Sps		buf[2] = '\0';
75060786Sps		parg.p_string = buf;
75160786Sps		error("quotes %s", &parg);
75260786Sps		break;
75360786Sps	}
75460786Sps}
75560786Sps
75660786Sps/*
757330571Sdelphij * Handler for the --rscroll option.
758330571Sdelphij */
759330571Sdelphij	/*ARGSUSED*/
760330571Sdelphij	public void
761330571Sdelphijopt_rscroll(type, s)
762330571Sdelphij	int type;
763330571Sdelphij	char *s;
764330571Sdelphij{
765330571Sdelphij	PARG p;
766330571Sdelphij
767330571Sdelphij	switch (type)
768330571Sdelphij	{
769330571Sdelphij	case INIT:
770330571Sdelphij	case TOGGLE: {
771330571Sdelphij		char *fmt;
772330571Sdelphij		int attr = AT_STANDOUT;
773330571Sdelphij		setfmt(s, &fmt, &attr, "*s>");
774330571Sdelphij		if (strcmp(fmt, "-") == 0)
775330571Sdelphij		{
776330571Sdelphij			rscroll_char = 0;
777330571Sdelphij		} else
778330571Sdelphij		{
779330571Sdelphij			rscroll_char = *fmt ? *fmt : '>';
780330571Sdelphij			rscroll_attr = attr;
781330571Sdelphij		}
782330571Sdelphij		break; }
783330571Sdelphij	case QUERY: {
784330571Sdelphij		p.p_string = rscroll_char ? prchar(rscroll_char) : "-";
785330571Sdelphij		error("rscroll char is %s", &p);
786330571Sdelphij		break; }
787330571Sdelphij	}
788330571Sdelphij}
789330571Sdelphij
790330571Sdelphij/*
79160786Sps * "-?" means display a help message.
79260786Sps * If from the command line, exit immediately.
79360786Sps */
79460786Sps	/*ARGSUSED*/
79560786Sps	public void
79660786Spsopt_query(type, s)
79760786Sps	int type;
79860786Sps	char *s;
79960786Sps{
80060786Sps	switch (type)
80160786Sps	{
80260786Sps	case QUERY:
80360786Sps	case TOGGLE:
80460786Sps		error("Use \"h\" for help", NULL_PARG);
80560786Sps		break;
80660786Sps	case INIT:
80760786Sps		dohelp = 1;
80860786Sps	}
80960786Sps}
81060786Sps
81160786Sps/*
81260786Sps * Get the "screen window" size.
81360786Sps */
81460786Sps	public int
81560786Spsget_swindow()
81660786Sps{
81760786Sps	if (swindow > 0)
81860786Sps		return (swindow);
81960786Sps	return (sc_height + swindow);
82060786Sps}
82160786Sps
822