opttbl.c revision 63128
160786Sps/*
260786Sps * Copyright (C) 1984-2000  Mark Nudelman
360786Sps *
460786Sps * You may distribute under the terms of either the GNU General Public
560786Sps * License or the Less License, as specified in the README file.
660786Sps *
760786Sps * For more information about less, or for information on how to
860786Sps * contact the author, see the README file.
960786Sps */
1060786Sps
1160786Sps
1260786Sps/*
1360786Sps * The option table.
1460786Sps */
1560786Sps
1660786Sps#include "less.h"
1760786Sps#include "option.h"
1860786Sps
1960786Sps/*
2060786Sps * Variables controlled by command line options.
2160786Sps */
2260786Spspublic int quiet;		/* Should we suppress the audible bell? */
2360786Spspublic int how_search;		/* Where should forward searches start? */
2460786Spspublic int top_scroll;		/* Repaint screen from top?
2560786Sps				   (alternative is scroll from bottom) */
2660786Spspublic int pr_type;		/* Type of prompt (short, medium, long) */
2760786Spspublic int bs_mode;		/* How to process backspaces */
2860786Spspublic int know_dumb;		/* Don't complain about dumb terminals */
2960786Spspublic int quit_at_eof;		/* Quit after hitting end of file twice */
3060786Spspublic int quit_if_one_screen;	/* Quit if EOF on first screen */
3160786Spspublic int squeeze;		/* Squeeze multiple blank lines into one */
3260786Spspublic int tabstop;		/* Tab settings */
3360786Spspublic int back_scroll;		/* Repaint screen on backwards movement */
3460786Spspublic int forw_scroll;		/* Repaint screen on forward movement */
3560786Spspublic int caseless;		/* Do "caseless" searches */
3660786Spspublic int linenums;		/* Use line numbers */
3760786Spspublic int cbufs;		/* Current number of buffers */
3860786Spspublic int autobuf;		/* Automatically allocate buffers as needed */
3960786Spspublic int ctldisp;		/* Send control chars to screen untranslated */
4060786Spspublic int force_open;		/* Open the file even if not regular file */
4160786Spspublic int swindow;		/* Size of scrolling window */
4260786Spspublic int jump_sline;		/* Screen line of "jump target" */
4360786Spspublic int chopline;		/* Truncate displayed lines at screen width */
4460786Spspublic int no_init;		/* Disable sending ti/te termcap strings */
4560786Spspublic int twiddle;             /* Show tildes after EOF */
4660786Spspublic int show_attn;		/* Hilite first unread line */
4763128Spspublic int shift_count;		/* Number of positions to shift horizontally */
4863128Spspublic int status_col;		/* Display a status column */
4960786Sps#if HILITE_SEARCH
5060786Spspublic int hilite_search;	/* Highlight matched search patterns? */
5160786Sps#endif
5260786Sps
5360786Sps/*
5460786Sps * Long option names.
5560786Sps */
5660786Spsstatic struct optname a_optname      = { "search-skip-screen",   NULL };
5760786Spsstatic struct optname b_optname      = { "buffers",              NULL };
5860786Spsstatic struct optname B__optname     = { "auto-buffers",         NULL };
5960786Spsstatic struct optname c_optname      = { "clear-screen",         NULL };
6060786Spsstatic struct optname d_optname      = { "dumb",                 NULL };
6160786Sps#if MSDOS_COMPILER
6260786Spsstatic struct optname D__optname     = { "color",                NULL };
6360786Sps#endif
6460786Spsstatic struct optname e_optname      = { "quit-at-eof",          NULL };
6560786Spsstatic struct optname f_optname      = { "force",                NULL };
6660786Spsstatic struct optname F__optname     = { "quit-if-one-screen",   NULL };
6760786Sps#if HILITE_SEARCH
6860786Spsstatic struct optname g_optname      = { "hilite-search",        NULL };
6960786Sps#endif
7060786Spsstatic struct optname h_optname      = { "max-back-scroll",      NULL };
7160786Spsstatic struct optname i_optname      = { "ignore-case",          NULL };
7260786Spsstatic struct optname j_optname      = { "jump-target",          NULL };
7363128Spsstatic struct optname J__optname     = { "status-column",        NULL };
7460786Sps#if USERFILE
7560786Spsstatic struct optname k_optname      = { "lesskey-file",         NULL };
7660786Sps#endif
7760786Spsstatic struct optname m_optname      = { "long-prompt",          NULL };
7860786Spsstatic struct optname n_optname      = { "line-numbers",         NULL };
7960786Sps#if LOGFILE
8060786Spsstatic struct optname o_optname      = { "log-file",             NULL };
8160786Spsstatic struct optname O__optname     = { "LOG-FILE",             NULL };
8260786Sps#endif
8360786Spsstatic struct optname p_optname      = { "pattern",              NULL };
8460786Spsstatic struct optname P__optname     = { "prompt",               NULL };
8560786Spsstatic struct optname q2_optname     = { "silent",               NULL };
8660786Spsstatic struct optname q_optname      = { "quiet",                &q2_optname };
8760786Spsstatic struct optname r_optname      = { "raw-control-chars",    NULL };
8860786Spsstatic struct optname s_optname      = { "squeeze-blank-lines",  NULL };
8960786Spsstatic struct optname S__optname     = { "chop-long-lines",      NULL };
9060786Sps#if TAGS
9160786Spsstatic struct optname t_optname      = { "tag",                  NULL };
9260786Spsstatic struct optname T__optname     = { "tag-file",             NULL };
9360786Sps#endif
9460786Spsstatic struct optname u_optname      = { "underline-special",    NULL };
9560786Spsstatic struct optname V__optname     = { "version",              NULL };
9660786Spsstatic struct optname w_optname      = { "hilite-unread",        NULL };
9760786Spsstatic struct optname x_optname      = { "tabs",                 NULL };
9860786Spsstatic struct optname X__optname     = { "no-init",              NULL };
9960786Spsstatic struct optname y_optname      = { "max-forw-scroll",      NULL };
10060786Spsstatic struct optname z_optname      = { "window",               NULL };
10160786Spsstatic struct optname quote_optname  = { "quotes",               NULL };
10260786Spsstatic struct optname tilde_optname  = { "tilde",                NULL };
10360786Spsstatic struct optname query_optname  = { "help",                 NULL };
10463128Spsstatic struct optname pound_optname  = { "shift",                NULL };
10560786Sps
10660786Sps
10760786Sps/*
10860786Sps * Table of all options and their semantics.
10960786Sps */
11060786Spsstatic struct option option[] =
11160786Sps{
11260786Sps	{ 'a', &a_optname,
11360786Sps		BOOL, OPT_OFF, &how_search, NULL,
11460786Sps		"Search includes displayed screen",
11560786Sps		"Search skips displayed screen",
11660786Sps		NULL
11760786Sps	},
11860786Sps
11960786Sps	{ 'b', &b_optname,
12060786Sps		NUMBER, 10, &cbufs, opt_b,
12160786Sps		"Buffers: ",
12260786Sps		"%d buffers",
12360786Sps		NULL
12460786Sps	},
12560786Sps	{ 'B', &B__optname,
12660786Sps		BOOL, OPT_ON, &autobuf, NULL,
12760786Sps		"Don't automatically allocate buffers",
12860786Sps		"Automatically allocate buffers when needed",
12960786Sps		NULL
13060786Sps	},
13160786Sps	{ 'c', &c_optname,
13260786Sps		TRIPLE, OPT_OFF, &top_scroll, NULL,
13360786Sps		"Repaint by scrolling from bottom of screen",
13460786Sps		"Repaint by clearing each line",
13560786Sps		"Repaint by painting from top of screen"
13660786Sps	},
13760786Sps	{ 'd', &d_optname,
13860786Sps		BOOL|NO_TOGGLE, OPT_OFF, &know_dumb, NULL,
13960786Sps		"Assume intelligent terminal",
14060786Sps		"Assume dumb terminal",
14160786Sps		NULL
14260786Sps	},
14360786Sps#if MSDOS_COMPILER
14460786Sps	{ 'D', &D__optname,
14560786Sps		STRING|REPAINT|NO_QUERY, 0, NULL, opt_D,
14660786Sps		"color desc: ", NULL, NULL
14760786Sps	},
14860786Sps#endif
14960786Sps	{ 'e', &e_optname,
15060786Sps		TRIPLE, OPT_OFF, &quit_at_eof, NULL,
15160786Sps		"Don't quit at end-of-file",
15260786Sps		"Quit at end-of-file",
15360786Sps		"Quit immediately at end-of-file"
15460786Sps	},
15560786Sps	{ 'f', &f_optname,
15660786Sps		BOOL, OPT_OFF, &force_open, NULL,
15760786Sps		"Open only regular files",
15860786Sps		"Open even non-regular files",
15960786Sps		NULL
16060786Sps	},
16160786Sps	{ 'F', &F__optname,
16260786Sps		BOOL, OPT_OFF, &quit_if_one_screen, NULL,
16360786Sps		"Don't quit if end-of-file on first screen",
16460786Sps		"Quit if end-of-file on first screen",
16560786Sps		NULL
16660786Sps	},
16760786Sps#if HILITE_SEARCH
16860786Sps	{ 'g', &g_optname,
16960786Sps		TRIPLE|HL_REPAINT, OPT_ONPLUS, &hilite_search, NULL,
17060786Sps		"Don't highlight search matches",
17160786Sps		"Highlight matches for previous search only",
17260786Sps		"Highlight all matches for previous search pattern",
17360786Sps	},
17460786Sps#endif
17560786Sps	{ 'h', &h_optname,
17660786Sps		NUMBER, -1, &back_scroll, NULL,
17760786Sps		"Backwards scroll limit: ",
17860786Sps		"Backwards scroll limit is %d lines",
17960786Sps		NULL
18060786Sps	},
18160786Sps	{ 'i', &i_optname,
18260786Sps		TRIPLE|HL_REPAINT, OPT_OFF, &caseless, opt_i,
18360786Sps		"Case is significant in searches",
18460786Sps		"Ignore case in searches",
18560786Sps		"Ignore case in searches and in patterns"
18660786Sps	},
18760786Sps	{ 'j', &j_optname,
18860786Sps		NUMBER, 1, &jump_sline, NULL,
18960786Sps		"Target line: ",
19060786Sps		"Position target at screen line %d",
19160786Sps		NULL
19260786Sps	},
19363128Sps	{ 'J', &J__optname,
19463128Sps		BOOL|REPAINT, OPT_OFF, &status_col, NULL,
19563128Sps		"Don't display a status column",
19663128Sps		"Display a status column",
19763128Sps		NULL
19863128Sps	},
19960786Sps#if USERFILE
20060786Sps	{ 'k', &k_optname,
20160786Sps		STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_k,
20260786Sps		NULL, NULL, NULL
20360786Sps	},
20460786Sps#endif
20560786Sps	{ 'l', NULL,
20660786Sps		STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_l,
20760786Sps		NULL, NULL, NULL
20860786Sps	},
20960786Sps	{ 'm', &m_optname,
21060786Sps		TRIPLE, OPT_OFF, &pr_type, NULL,
21160786Sps		"Short prompt",
21260786Sps		"Medium prompt",
21360786Sps		"Long prompt"
21460786Sps	},
21560786Sps	{ 'n', &n_optname,
21660786Sps		TRIPLE|REPAINT, OPT_ON, &linenums, NULL,
21760786Sps		"Don't use line numbers",
21860786Sps		"Use line numbers",
21960786Sps		"Constantly display line numbers"
22060786Sps	},
22160786Sps#if LOGFILE
22260786Sps	{ 'o', &o_optname,
22360786Sps		STRING, 0, NULL, opt_o,
22460786Sps		"log file: ", NULL, NULL
22560786Sps	},
22660786Sps	{ 'O', &O__optname,
22760786Sps		STRING, 0, NULL, opt__O,
22860786Sps		"Log file: ", NULL, NULL
22960786Sps	},
23060786Sps#endif
23160786Sps	{ 'p', &p_optname,
23260786Sps		STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_p,
23360786Sps		NULL, NULL, NULL
23460786Sps	},
23560786Sps	{ 'P', &P__optname,
23660786Sps		STRING, 0, NULL, opt__P,
23760786Sps		"prompt: ", NULL, NULL
23860786Sps	},
23960786Sps	{ 'q', &q_optname,
24060786Sps		TRIPLE, OPT_OFF, &quiet, NULL,
24160786Sps		"Ring the bell for errors AND at eof/bof",
24260786Sps		"Ring the bell for errors but not at eof/bof",
24360786Sps		"Never ring the bell"
24460786Sps	},
24560786Sps	{ 'r', &r_optname,
24660786Sps		TRIPLE|REPAINT, OPT_OFF, &ctldisp, NULL,
24760786Sps		"Display control characters as ^X",
24860786Sps		"Display control characters directly",
24960786Sps		"Display control characters directly, processing ANSI sequences"
25060786Sps	},
25160786Sps	{ 's', &s_optname,
25260786Sps		BOOL|REPAINT, OPT_OFF, &squeeze, NULL,
25360786Sps		"Display all blank lines",
25460786Sps		"Squeeze multiple blank lines",
25560786Sps		NULL
25660786Sps	},
25760786Sps	{ 'S', &S__optname,
25860786Sps		BOOL|REPAINT, OPT_OFF, &chopline, NULL,
25960786Sps		"Fold long lines",
26060786Sps		"Chop long lines",
26160786Sps		NULL
26260786Sps	},
26360786Sps#if TAGS
26460786Sps	{ 't', &t_optname,
26560786Sps		STRING|NO_QUERY, 0, NULL, opt_t,
26660786Sps		"tag: ", NULL, NULL
26760786Sps	},
26860786Sps	{ 'T', &T__optname,
26960786Sps		STRING, 0, NULL, opt__T,
27060786Sps		"tags file: ", NULL, NULL
27160786Sps	},
27260786Sps#endif
27360786Sps	{ 'u', &u_optname,
27460786Sps		TRIPLE|REPAINT, OPT_OFF, &bs_mode, NULL,
27560786Sps		"Display underlined text in underline mode",
27660786Sps		"Backspaces cause overstrike",
27760786Sps		"Print backspace as ^H"
27860786Sps	},
27960786Sps	{ 'V', &V__optname,
28060786Sps		NOVAR, 0, NULL, opt__V,
28160786Sps		NULL, NULL, NULL
28260786Sps	},
28360786Sps	{ 'w', &w_optname,
28460786Sps		TRIPLE|REPAINT, OPT_OFF, &show_attn, NULL,
28560786Sps		"Don't highlight first unread line",
28660786Sps		"Highlight first unread line after forward-screen",
28760786Sps		"Highlight first unread line after any forward movement",
28860786Sps	},
28960786Sps	{ 'x', &x_optname,
29060786Sps		NUMBER|REPAINT, 8, &tabstop, NULL,
29160786Sps		"Tab stops: ",
29260786Sps		"Tab stops every %d spaces",
29360786Sps		NULL
29460786Sps	},
29560786Sps	{ 'X', &X__optname,
29660786Sps		BOOL|NO_TOGGLE, OPT_OFF, &no_init, NULL,
29760786Sps		"Send init/deinit strings to terminal",
29860786Sps		"Don't use init/deinit strings",
29960786Sps		NULL
30060786Sps	},
30160786Sps	{ 'y', &y_optname,
30260786Sps		NUMBER, -1, &forw_scroll, NULL,
30360786Sps		"Forward scroll limit: ",
30460786Sps		"Forward scroll limit is %d lines",
30560786Sps		NULL
30660786Sps	},
30760786Sps	{ 'z', &z_optname,
30860786Sps		NUMBER, -1, &swindow, NULL,
30960786Sps		"Scroll window size: ",
31060786Sps		"Scroll window size is %d lines",
31160786Sps		NULL
31260786Sps	},
31360786Sps	{ '"', &quote_optname,
31460786Sps		STRING, 0, NULL, opt_quote,
31560786Sps		"quotes: ", NULL, NULL
31660786Sps	},
31760786Sps	{ '~', &tilde_optname,
31860786Sps		BOOL|REPAINT, OPT_ON, &twiddle, NULL,
31960786Sps		"Don't show tildes after end of file",
32060786Sps		"Show tildes after end of file",
32160786Sps		NULL
32260786Sps	},
32360786Sps	{ '?', &query_optname,
32460786Sps		NOVAR, 0, NULL, opt_query,
32560786Sps		NULL, NULL, NULL
32660786Sps	},
32763128Sps	{ '#', &pound_optname,
32863128Sps		NUMBER, 0, &shift_count, NULL,
32963128Sps		"Horizontal shift: ",
33063128Sps		"Horizontal shift %d positions",
33163128Sps		NULL
33263128Sps	},
33360786Sps	{ '\0', NULL, NOVAR, 0, NULL, NULL, NULL, NULL, NULL }
33460786Sps};
33560786Sps
33660786Sps
33760786Sps/*
33860786Sps * Initialize each option to its default value.
33960786Sps */
34060786Sps	public void
34160786Spsinit_option()
34260786Sps{
34360786Sps	register struct option *o;
34460786Sps
34560786Sps	for (o = option;  o->oletter != '\0';  o++)
34660786Sps	{
34760786Sps		/*
34860786Sps		 * Set each variable to its default.
34960786Sps		 */
35060786Sps		if (o->ovar != NULL)
35160786Sps			*(o->ovar) = o->odefault;
35260786Sps	}
35360786Sps}
35460786Sps
35560786Sps/*
35660786Sps * Find an option in the option table, given its option letter.
35760786Sps */
35860786Sps	public struct option *
35960786Spsfindopt(c)
36060786Sps	int c;
36160786Sps{
36260786Sps	register struct option *o;
36360786Sps
36460786Sps	for (o = option;  o->oletter != '\0';  o++)
36560786Sps	{
36660786Sps		if (o->oletter == c)
36760786Sps			return (o);
36860786Sps		if ((o->otype & TRIPLE) && toupper(o->oletter) == c)
36960786Sps			return (o);
37060786Sps	}
37160786Sps	return (NULL);
37260786Sps}
37360786Sps
37460786Sps/*
37560786Sps * Find an option in the option table, given its option name.
37660786Sps * p_optname is the (possibly partial) name to look for, and
37760786Sps * is updated to point after the matched name.
37860786Sps * p_oname if non-NULL is set to point to the full option name.
37960786Sps */
38060786Sps	public struct option *
38160786Spsfindopt_name(p_optname, p_oname, p_err)
38260786Sps	char **p_optname;
38360786Sps	char **p_oname;
38460786Sps	int *p_err;
38560786Sps{
38660786Sps	char *optname = *p_optname;
38760786Sps	register struct option *o;
38860786Sps	register struct optname *oname;
38960786Sps	register int len;
39060786Sps	int uppercase;
39160786Sps	struct option *maxo = NULL;
39260786Sps	struct optname *maxoname = NULL;
39360786Sps	int maxlen = 0;
39460786Sps	int ambig = 0;
39560786Sps	int exact = 0;
39660786Sps
39760786Sps	/*
39860786Sps	 * Check all options.
39960786Sps	 */
40060786Sps	for (o = option;  o->oletter != '\0';  o++)
40160786Sps	{
40260786Sps		/*
40360786Sps		 * Check all names for this option.
40460786Sps		 */
40560786Sps		for (oname = o->onames;  oname != NULL;  oname = oname->onext)
40660786Sps		{
40760786Sps			/*
40860786Sps			 * Try normal match first (uppercase == 0),
40960786Sps			 * then, then if it's a TRIPLE option,
41060786Sps			 * try uppercase match (uppercase == 1).
41160786Sps			 */
41260786Sps			for (uppercase = 0;  uppercase <= 1;  uppercase++)
41360786Sps			{
41460786Sps				len = sprefix(optname, oname->oname, uppercase);
41560786Sps				if (!exact && len == maxlen)
41660786Sps					/*
41760786Sps					 * Already had a partial match,
41860786Sps					 * and now there's another one that
41960786Sps					 * matches the same length.
42060786Sps					 */
42160786Sps					ambig = 1;
42260786Sps				else if (len > maxlen)
42360786Sps				{
42460786Sps					/*
42560786Sps					 * Found a better match than
42660786Sps					 * the one we had.
42760786Sps					 */
42860786Sps					maxo = o;
42960786Sps					maxoname = oname;
43060786Sps					maxlen = len;
43160786Sps					ambig = 0;
43260786Sps					exact = (len == strlen(oname->oname));
43360786Sps				}
43460786Sps				if (!(o->otype & TRIPLE))
43560786Sps					break;
43660786Sps			}
43760786Sps		}
43860786Sps	}
43960786Sps	if (ambig)
44060786Sps	{
44160786Sps		/*
44260786Sps		 * Name matched more than one option.
44360786Sps		 */
44460786Sps		if (p_err != NULL)
44560786Sps			*p_err = OPT_AMBIG;
44660786Sps		return (NULL);
44760786Sps	}
44860786Sps	*p_optname = optname + maxlen;
44960786Sps	if (p_oname != NULL)
45060786Sps		*p_oname = maxoname->oname;
45160786Sps	return (maxo);
45260786Sps}
453