798 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			798 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /* opts.c */
 | |
| 
 | |
| /* Author:
 | |
|  *	Steve Kirkendall
 | |
|  *	14407 SW Teal Blvd. #C
 | |
|  *	Beaverton, OR 97005
 | |
|  *	kirkenda@cs.pdx.edu
 | |
|  */
 | |
| 
 | |
| 
 | |
| /* This file contains the code that manages the run-time options -- The 
 | |
|  * values that can be modified via the "set" command.
 | |
|  */
 | |
| 
 | |
| #include "config.h"
 | |
| #include "vi.h"
 | |
| #include "ctype.h"
 | |
| #ifndef NULL
 | |
| #define NULL (char *)0
 | |
| #endif
 | |
| extern char	*getenv();
 | |
| 
 | |
| /* maximum width to permit for strings, including ="" */
 | |
| #define MAXWIDTH 20
 | |
| 
 | |
| /* These are the default values of all options */
 | |
| char	o_autoindent[1] =	{FALSE};
 | |
| char	o_autoprint[1] =	{TRUE};
 | |
| char	o_autotab[1] =		{TRUE};
 | |
| char	o_autowrite[1] = 	{FALSE};
 | |
| char	o_columns[3] =		{80, 32, 255};
 | |
| char	o_directory[30] =	TMPDIR;
 | |
| char	o_edcompatible[1] =	{FALSE};
 | |
| char	o_equalprg[80] =	{"fmt"};
 | |
| char	o_errorbells[1] =	{TRUE};
 | |
| char	o_exrefresh[1] =	{TRUE};
 | |
| char	o_ignorecase[1] =	{FALSE};
 | |
| char	o_keytime[3] =		{1, 0, 50};
 | |
| char	o_keywordprg[80] =	{KEYWORDPRG};
 | |
| char	o_lines[3] =		{25, 2, 96};
 | |
| char	o_list[1] =		{FALSE};
 | |
| char	o_number[1] =		{FALSE};
 | |
| char	o_readonly[1] =		{FALSE};
 | |
| char	o_remap[1] =		{TRUE};
 | |
| char	o_report[3] =		{5, 1, 127};
 | |
| char	o_scroll[3] =		{12, 1, 127};
 | |
| char	o_shell[60] =		SHELL;
 | |
| char	o_shiftwidth[3] =	{8, 1, 255};
 | |
| char	o_sidescroll[3] =	{8, 1, 40};
 | |
| char	o_sync[1] =		{NEEDSYNC};
 | |
| char	o_tabstop[3] =		{8, 1, 40};
 | |
| char	o_term[30] =		"?";
 | |
| char	o_flash[1] =		{TRUE};
 | |
| char	o_warn[1] =		{TRUE};
 | |
| char	o_wrapscan[1] =		{TRUE};
 | |
| 
 | |
| #ifndef CRUNCH
 | |
| char	o_beautify[1] =		{FALSE};
 | |
| char	o_exrc[1] =		{FALSE};
 | |
| char	o_mesg[1] =		{TRUE};
 | |
| char	o_more[1] =		{TRUE};
 | |
| char	o_novice[1] =		{FALSE};
 | |
| char	o_prompt[1] =		{TRUE};
 | |
| char	o_taglength[3] =	{0, 0, 30};
 | |
| char	o_terse[1] =		{FALSE};
 | |
| char	o_window[3] =		{0, 1, 24};
 | |
| char	o_wrapmargin[3] =	{0, 0, 255};
 | |
| char	o_writeany[1] =		{FALSE};
 | |
| #endif
 | |
| 
 | |
| #ifndef NO_ERRLIST
 | |
| char	o_cc[30] =		{CC_COMMAND};
 | |
| char	o_make[30] =		{MAKE_COMMAND};
 | |
| #endif
 | |
| 
 | |
| #ifndef NO_CHARATTR
 | |
| char	o_charattr[1] =		{FALSE};
 | |
| #endif
 | |
| 
 | |
| #ifndef NO_DIGRAPH
 | |
| char	o_digraph[1] =		{FALSE};
 | |
| char	o_flipcase[80]
 | |
| # ifdef CS_IBMPC
 | |
| 	= {"\207\200\201\232\202\220\204\216\206\217\221\222\224\231\244\245"}
 | |
| # endif
 | |
| # ifdef CS_LATIN1
 | |
| 	/* initialized by initopts() */
 | |
| # endif
 | |
| 	;
 | |
| #endif
 | |
| 
 | |
| #ifndef NO_SENTENCE
 | |
| char	o_hideformat[1] =	{FALSE};
 | |
| #endif
 | |
| 
 | |
| #ifndef NO_EXTENSIONS
 | |
| char	o_inputmode[1] =	{FALSE};
 | |
| char	o_ruler[1] =		{FALSE};
 | |
| #endif
 | |
| 
 | |
| #ifndef NO_MAGIC
 | |
| char	o_magic[1] =		{TRUE};
 | |
| #endif
 | |
| 
 | |
| #ifndef NO_MODELINES
 | |
| char	o_modelines[1] =	{FALSE};
 | |
| #endif
 | |
| 
 | |
| #ifndef NO_SENTENCE
 | |
| char	o_paragraphs[30] =	"PPppIPLPQP";
 | |
| char	o_sections[30] =	"NHSHSSSEse";
 | |
| #endif
 | |
| 
 | |
| #if MSDOS
 | |
| char	o_pcbios[1] =		{TRUE};
 | |
| #endif
 | |
| 
 | |
| #ifndef NO_SHOWMATCH
 | |
| char	o_showmatch[1] =	{FALSE};
 | |
| #endif
 | |
| 
 | |
| #ifndef	NO_SHOWMODE
 | |
| char	o_smd[1] =		{FALSE};
 | |
| #endif
 | |
| 
 | |
| 
 | |
| /* The following describes the names & types of all options */
 | |
| #define BOOL	0
 | |
| #define	NUM	1
 | |
| #define	STR	2
 | |
| #define SET	0x01	/* this option has had its value altered */
 | |
| #define CANSET	0x02	/* this option can be set at any time */
 | |
| #define RCSET	0x06	/* this option can be set in a .exrc file only */
 | |
| #define NOSAVE	0x0a	/* this option should never be saved by mkexrc */
 | |
| #define WSET	0x20	/* is this the "window" size option? */
 | |
| #define MR	0x40	/* does this option affect the way text is displayed? */
 | |
| struct
 | |
| {
 | |
| 	char	*name;	/* name of an option */
 | |
| 	char	*nm;	/* short name of an option */
 | |
| 	char	type;	/* type of an option */
 | |
| 	char	flags;	/* boolean: has this option been set? */
 | |
| 	char	*value;	/* value */
 | |
| }
 | |
| 	opts[] =
 | |
| {
 | |
| 	/* name			type	flags		value */
 | |
| 	{ "autoindent",	"ai",	BOOL,	CANSET,		o_autoindent	},
 | |
| 	{ "autoprint",	"ap",	BOOL,	CANSET,		o_autoprint	},
 | |
| 	{ "autotab",	"at",	BOOL,	CANSET,		o_autotab	},
 | |
| 	{ "autowrite",	"aw",	BOOL,	CANSET,		o_autowrite	},
 | |
| #ifndef CRUNCH
 | |
| 	{ "beautify",	"bf",	BOOL,	CANSET,		o_beautify	},
 | |
| #endif
 | |
| #ifndef NO_ERRLIST
 | |
| 	{ "cc",		"cc",	STR,	CANSET,		o_cc		},
 | |
| #endif
 | |
| #ifndef NO_CHARATTR
 | |
| 	{ "charattr",	"ca",	BOOL,	CANSET|MR,	o_charattr	},
 | |
| #endif
 | |
| 	{ "columns",	"co",	NUM,	SET|NOSAVE|MR,	o_columns	},
 | |
| #ifndef NO_DIGRAPH
 | |
| 	{ "digraph",	"dig",	BOOL,	CANSET,		o_digraph	},
 | |
| #endif
 | |
| 	{ "directory",	"dir",	STR,	RCSET,		o_directory	},
 | |
| 	{ "edcompatible","ed",	BOOL,	CANSET,		o_edcompatible	},
 | |
| 	{ "equalprg",	"ep",	STR,	CANSET,		o_equalprg	},
 | |
| 	{ "errorbells",	"eb",	BOOL,	CANSET,		o_errorbells	},
 | |
| #ifndef CRUNCH
 | |
| 	{ "exrc",	"exrc",	BOOL,	CANSET,		o_exrc		},
 | |
| #endif
 | |
| 	{ "exrefresh",	"er",	BOOL,	CANSET,		o_exrefresh	},
 | |
| 	{ "flash",	"vbell",BOOL,	CANSET,		o_flash		},
 | |
| #ifndef NO_DIGRAPH
 | |
| 	{ "flipcase",	"fc",	STR,	CANSET,		o_flipcase	},
 | |
| #endif
 | |
| #ifndef NO_SENTENCE
 | |
| 	{ "hideformat",	"hf",	BOOL,	CANSET|MR,	o_hideformat	},
 | |
| #endif
 | |
| 	{ "ignorecase",	"ic",	BOOL,	CANSET,		o_ignorecase	},
 | |
| #ifndef NO_EXTENSIONS
 | |
| 	{ "inputmode",	"im",	BOOL,	CANSET,		o_inputmode	},
 | |
| #endif
 | |
| 	{ "keytime",	"kt",	NUM,	CANSET,		o_keytime	},
 | |
| 	{ "keywordprg",	"kp",	STR,	CANSET,		o_keywordprg	},
 | |
| 	{ "lines",	"ls",	NUM,	SET|NOSAVE|MR,	o_lines		},
 | |
| 	{ "list",	"li",	BOOL,	CANSET|MR,	o_list		},
 | |
| #ifndef NO_MAGIC
 | |
| 	{ "magic",	"ma",	BOOL,	CANSET,		o_magic		},
 | |
| #endif
 | |
| #ifndef NO_ERRLIST
 | |
| 	{ "make",	"mk",	STR,	CANSET,		o_make		},
 | |
| #endif
 | |
| #ifndef CRUNCH
 | |
| 	{ "mesg",	"me",	BOOL,	CANSET,		o_mesg		},
 | |
| #endif
 | |
| #ifndef NO_MODELINES
 | |
| 	{ "modelines",	"ml",	BOOL,	CANSET,		o_modelines	},
 | |
| #endif
 | |
| #ifndef CRUNCH
 | |
| 	{ "more",	"mo",	BOOL,	CANSET,		o_more		},
 | |
| 	{ "novice",	"nov",	BOOL,	CANSET,		o_novice	},
 | |
| #endif
 | |
| 	{ "number",	"nu",	BOOL,	CANSET|MR,	o_number	},
 | |
| #ifndef NO_SENTENCE
 | |
| 	{ "paragraphs",	"para",	STR,	CANSET,		o_paragraphs	},
 | |
| #endif
 | |
| #if MSDOS
 | |
| 	{ "pcbios",	"pc",	BOOL,	SET|NOSAVE,	o_pcbios	},
 | |
| #endif
 | |
| #ifndef CRUNCH
 | |
| 	{ "prompt",	"pr",	BOOL,	CANSET,		o_prompt	},
 | |
| #endif
 | |
| 	{ "readonly",	"ro",	BOOL,	CANSET,		o_readonly	},
 | |
| 	{ "remap",	"remap",BOOL,	CANSET,		o_remap		},
 | |
| 	{ "report",	"re",	NUM,	CANSET,		o_report	},
 | |
| #ifndef NO_EXTENSIONS
 | |
| 	{ "ruler",	"ru",	BOOL,	CANSET,		o_ruler		},
 | |
| #endif
 | |
| 	{ "scroll",	"sc",	NUM,	CANSET,		o_scroll	},
 | |
| #ifndef NO_SENTENCE
 | |
| 	{ "sections",	"sect",	STR,	CANSET,		o_sections	},
 | |
| #endif
 | |
| 	{ "shell",	"sh",	STR,	CANSET,		o_shell		},
 | |
| #ifndef NO_SHOWMATCH
 | |
| 	{ "showmatch",	"sm",	BOOL,	CANSET,		o_showmatch	},
 | |
| #endif
 | |
| #ifndef	NO_SHOWMODE
 | |
| 	{ "showmode",	"smd",	BOOL,	CANSET,		o_smd		},
 | |
| #endif
 | |
| 	{ "shiftwidth",	"sw",	NUM,	CANSET,		o_shiftwidth	},
 | |
| 	{ "sidescroll",	"ss",	NUM,	CANSET,		o_sidescroll	},
 | |
| 	{ "sync",	"sy",	BOOL,	CANSET,		o_sync		},
 | |
| 	{ "tabstop",	"ts",	NUM,	CANSET|MR,	o_tabstop	},
 | |
| #ifndef CRUNCH
 | |
| 	{ "taglength",	"tl",	NUM,	CANSET,		o_taglength	},
 | |
| #endif
 | |
| 	{ "term",	"te",	STR,	SET,		o_term		},
 | |
| #ifndef CRUNCH
 | |
| 	{ "terse",	"tr",	BOOL,	CANSET,		o_terse		},
 | |
| 	{ "timeout",	"to",	BOOL,	CANSET,		o_keytime	},
 | |
| #endif
 | |
| #ifndef CRUNCH
 | |
| 	{ "window",	"wi",	NUM,	CANSET|MR|WSET,	o_window	},
 | |
| 	{ "wrapmargin",	"wm",	NUM,	CANSET,		o_wrapmargin	},
 | |
| #endif
 | |
| 	{ "wrapscan",	"ws",	BOOL,	CANSET,		o_wrapscan	},
 | |
| #ifndef CRUNCH
 | |
| 	{ "writeany",	"wr",	BOOL,	CANSET,		o_writeany	},
 | |
| #endif
 | |
| 	{ NULL, NULL, 0, CANSET, NULL }
 | |
| };
 | |
| 
 | |
| 
 | |
| /* This function initializes certain options from environment variables, etc. */
 | |
| void initopts()
 | |
| {
 | |
| 	char	*val;
 | |
| 	int	i;
 | |
| 
 | |
| 	/* set some stuff from environment variables */
 | |
| #if MSDOS
 | |
| 	if (val = getenv("COMSPEC")) /* yes, ASSIGNMENT! */
 | |
| #else
 | |
| 	if (val = getenv("SHELL")) /* yes, ASSIGNMENT! */
 | |
| #endif
 | |
| 	{
 | |
| 		strcpy(o_shell, val);
 | |
| 	}
 | |
| 
 | |
| 	strcpy(o_term, termtype);
 | |
| #if MSDOS
 | |
| 	if (strcmp(termtype, "pcbios"))
 | |
| 	{
 | |
| 		o_pcbios[0] = FALSE;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		o_pcbios[0] = TRUE;
 | |
| 	}
 | |
| #endif
 | |
| 
 | |
| #if AMIGA || MSDOS || TOS
 | |
| 	if ((val = getenv("TMP")) /* yes, ASSIGNMENT! */
 | |
| 	||  (val = getenv("TEMP")))
 | |
| 		strcpy(o_directory, val);
 | |
| #endif
 | |
| 
 | |
| #ifndef CRUNCH
 | |
| 	if ((val = getenv("LINES")) && atoi(val) > 4) /* yes, ASSIGNMENT! */
 | |
| 	{
 | |
| 		LINES = atoi(val);
 | |
| 	}
 | |
| 	if ((val = getenv("COLUMNS")) && atoi(val) > 30) /* yes, ASSIGNMENT! */
 | |
| 	{
 | |
| 		COLS = atoi(val);
 | |
| 	}
 | |
| #endif
 | |
| 	*o_lines = LINES;
 | |
| 	*o_columns = COLS;
 | |
| 	*o_scroll = LINES / 2 - 1;
 | |
| #ifndef CRUNCH
 | |
| 	if (o_window[0] == 0)
 | |
| 	{
 | |
| 		o_window[0] = o_window[2] = *o_lines;
 | |
| 	}
 | |
| #endif
 | |
| 
 | |
| 	/* disable the flash option if we don't know how to do a flash */
 | |
| 	if (!has_VB)
 | |
| 	{
 | |
| 		for (i = 0; opts[i].value != o_flash; i++)
 | |
| 		{
 | |
| 		}
 | |
| 		opts[i].flags &= ~CANSET;
 | |
| 		*o_flash = FALSE;
 | |
| 	}
 | |
| 
 | |
| #ifndef NO_DIGRAPH
 | |
| # ifdef CS_LATIN1
 | |
| 	for (i = 0, val = o_flipcase; i < 32; i++)
 | |
| 	{
 | |
| 		/* leave out the multiply/divide symbols */
 | |
| 		if (i == 23)
 | |
| 			continue;
 | |
| 
 | |
| 		/* add lower/uppercase pair */
 | |
| 		*val++ = i + 0xe0;
 | |
| 		*val++ = i + 0xc0;
 | |
| 	}
 | |
| 	*val = '\0';
 | |
| # endif /* CS_LATIN1 */
 | |
| 
 | |
| 	/* initialize the ctype package */
 | |
| 	_ct_init(o_flipcase);
 | |
| #else
 | |
| 	_ct_init("");
 | |
| #endif /* not NO_DIGRAPH */
 | |
| }
 | |
| 
 | |
| /* This function lists the current values of all options */
 | |
| void dumpopts(all)
 | |
| 	int	all;	/* boolean: dump all options, or just set ones? */
 | |
| {
 | |
| #ifndef NO_OPTCOLS
 | |
| 	int	i, j, k;
 | |
| 	char	nbuf[4];	/* used for converting numbers to ASCII */
 | |
| 	int	widths[5];	/* width of each column, including gap */
 | |
| 	int	ncols;		/* number of columns */
 | |
| 	int	nrows;		/* number of options per column */
 | |
| 	int	nset;		/* number of options to be output */
 | |
| 	int	width;		/* width of a particular option */
 | |
| 	int	todump[60];	/* indicies of options to be dumped */
 | |
| 
 | |
| 	/* step 1: count the number of set options */
 | |
| 	for (nset = i = 0; opts[i].name; i++)
 | |
| 	{
 | |
| 		if (all || (opts[i].flags & SET))
 | |
| 		{
 | |
| 			todump[nset++] = i;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/* step two: try to use as many columns as possible */
 | |
| 	for (ncols = (nset > 5 ? 5 : nset); ncols > 1; ncols--)
 | |
| 	{
 | |
| 		/* how many would go in this column? */
 | |
| 		nrows = (nset + ncols - 1) / ncols;
 | |
| 
 | |
| 		/* figure out the width of each column */
 | |
| 		for (i = 0; i < ncols; i++)
 | |
| 		{
 | |
| 			widths[i] = 0;
 | |
| 			for (j = 0, k = nrows * i; j < nrows && k < nset; j++, k++)
 | |
| 			{
 | |
| 				/* figure out the width of a particular option */
 | |
| 				switch (opts[todump[k]].type)
 | |
| 				{
 | |
| 				  case BOOL:
 | |
| 					if (!*opts[todump[k]].value)
 | |
| 						width = 2;
 | |
| 					else
 | |
| 						width = 0;
 | |
| 					break;
 | |
| 
 | |
| 				  case STR:
 | |
| 					width = 3 + strlen(opts[todump[k]].value);
 | |
| 					if (width > MAXWIDTH)
 | |
| 						width = MAXWIDTH;
 | |
| 					break;
 | |
| 
 | |
| 				  case NUM:
 | |
| 					width = 4;
 | |
| 					break;
 | |
| 				}
 | |
| 				width += strlen(opts[todump[k]].name);
 | |
| 
 | |
| 				/* if this is the widest so far, widen col */
 | |
| 				if (width > widths[i])
 | |
| 				{
 | |
| 					widths[i] = width;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 		/* if the total width is narrow enough, then use it */
 | |
| 		for (width = -2, i = 0; i < ncols; i++)
 | |
| 		{
 | |
| 			width += widths[i] + 2;
 | |
| 		}
 | |
| 		if (width < COLS - 1)
 | |
| 		{
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/* step 3: output the columns */
 | |
| 	nrows = (nset + ncols - 1) / ncols;
 | |
| 	for (i = 0; i < nrows; i++)
 | |
| 	{
 | |
| 		for (j = 0; j < ncols; j++)
 | |
| 		{
 | |
| 			/* if we hit the end of the options, quit */
 | |
| 			k = i + j * nrows;
 | |
| 			if (k >= nset)
 | |
| 			{
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			/* output this option's value */
 | |
| 			width = 0;
 | |
| 			switch (opts[todump[k]].type)
 | |
| 			{
 | |
| 			  case BOOL:
 | |
| 				if (!*opts[todump[k]].value)
 | |
| 				{
 | |
| 					qaddch('n');
 | |
| 					qaddch('o');
 | |
| 					width = 2;
 | |
| 				}
 | |
| 				qaddstr(opts[todump[k]].name);
 | |
| 				width += strlen(opts[todump[k]].name);
 | |
| 				break;
 | |
| 
 | |
| 			  case NUM:
 | |
| 				sprintf(nbuf, "%-3d", UCHAR(*opts[todump[k]].value));
 | |
| 				qaddstr(opts[todump[k]].name);
 | |
| 				qaddch('=');
 | |
| 				qaddstr(nbuf);
 | |
| 				width = 4 + strlen(opts[todump[k]].name);
 | |
| 				break;
 | |
| 
 | |
| 			  case STR:
 | |
| 				qaddstr(opts[todump[k]].name);
 | |
| 				qaddch('=');
 | |
| 				qaddch('"');
 | |
| 				strcpy(tmpblk.c, opts[todump[k]].value);
 | |
| 				width = 3 + strlen(tmpblk.c);
 | |
| 				if (width > MAXWIDTH)
 | |
| 				{
 | |
| 					width = MAXWIDTH;
 | |
| 					strcpy(tmpblk.c + MAXWIDTH - 6, "...");
 | |
| 				}
 | |
| 				qaddstr(tmpblk.c);
 | |
| 				qaddch('"');
 | |
| 				width += strlen(opts[todump[k]].name);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			/* pad the field to the correct size */
 | |
| 			if (k + nrows <= nset)
 | |
| 			{
 | |
| 				while (width < widths[j] + 2)
 | |
| 				{
 | |
| 					qaddch(' ');
 | |
| 					width++;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		addch('\n');
 | |
| 		exrefresh();
 | |
| 	}
 | |
| #else
 | |
| 	int	i;
 | |
| 	int	col;
 | |
| 	char	nbuf[4];
 | |
| 
 | |
| 	for (i = col = 0; opts[i].name; i++)
 | |
| 	{
 | |
| 		/* if not set and not all, ignore this option */
 | |
| 		if (!all && !(opts[i].flags & SET))
 | |
| 		{
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		/* align this option in one of the columns */
 | |
| 		if (col > 52)
 | |
| 		{
 | |
| 			addch('\n');
 | |
| 			col = 0;
 | |
| 		}
 | |
| 		else if (col > 26)
 | |
| 		{
 | |
| 			while (col < 52)
 | |
| 			{
 | |
| 				qaddch(' ');
 | |
| 				col++;
 | |
| 			}
 | |
| 		}
 | |
| 		else if (col > 0)
 | |
| 		{
 | |
| 			while (col < 26)
 | |
| 			{
 | |
| 				qaddch(' ');
 | |
| 				col++;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		switch (opts[i].type)
 | |
| 		{
 | |
| 		  case BOOL:
 | |
| 			if (!*opts[i].value)
 | |
| 			{
 | |
| 				qaddch('n');
 | |
| 				qaddch('o');
 | |
| 				col += 2;
 | |
| 			}
 | |
| 			qaddstr(opts[i].name);
 | |
| 			col += strlen(opts[i].name);
 | |
| 			break;
 | |
| 
 | |
| 		  case NUM:
 | |
| 			sprintf(nbuf, "%-3d", UCHAR(*opts[i].value));
 | |
| 			qaddstr(opts[i].name);
 | |
| 			qaddch('=');
 | |
| 			qaddstr(nbuf);
 | |
| 			col += 4 + strlen(opts[i].name);
 | |
| 			break;
 | |
| 
 | |
| 		  case STR:
 | |
| 			qaddstr(opts[i].name);
 | |
| 			qaddch('=');
 | |
| 			qaddch('"');
 | |
| 			qaddstr(opts[i].value);
 | |
| 			qaddch('"');
 | |
| 			col += 3 + strlen(opts[i].name) + strlen(opts[i].value);
 | |
| 			break;
 | |
| 		}
 | |
| 		exrefresh();
 | |
| 	}
 | |
| 	if (col > 0)
 | |
| 	{
 | |
| 		addch('\n');
 | |
| 		exrefresh();
 | |
| 	}
 | |
| #endif
 | |
| }
 | |
| 
 | |
| #ifndef NO_MKEXRC
 | |
| /* This function saves the current configuration of options to a file */
 | |
| void saveopts(fd)
 | |
| 	int	fd;	/* file descriptor to write to */
 | |
| {
 | |
| 	int	i;
 | |
| 	char	buf[256], *pos;
 | |
| 
 | |
| 	/* write each set options */
 | |
| 	for (i = 0; opts[i].name; i++)
 | |
| 	{
 | |
| 		/* if unset or unsettable, ignore this option */
 | |
| 		if ((opts[i].flags & (SET|CANSET|NOSAVE)) != (SET|CANSET))
 | |
| 		{
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		strcpy(buf, "set ");
 | |
| 		pos = &buf[4];
 | |
| 		switch (opts[i].type)
 | |
| 		{
 | |
| 		  case BOOL:
 | |
| 			if (!*opts[i].value)
 | |
| 			{
 | |
| 				*pos++='n';
 | |
| 				*pos++='o';
 | |
| 			}
 | |
| 			strcpy(pos, opts[i].name);
 | |
| 			strcat(pos, "\n");
 | |
| 			break;
 | |
| 
 | |
| 		  case NUM:
 | |
| 			sprintf(pos, "%s=%-3d\n", opts[i].name, *opts[i].value & 0xff);
 | |
| 			break;
 | |
| 
 | |
| 		  case STR:
 | |
| 			sprintf(pos, "%s=\"%s\"\n", opts[i].name, opts[i].value);
 | |
| 			break;
 | |
| 		}
 | |
| 		twrite(fd, buf, (unsigned)strlen(buf));
 | |
| 	}
 | |
| }
 | |
| #endif
 | |
| 
 | |
| 
 | |
| /* This function changes the values of one or more options. */
 | |
| void setopts(assignments)
 | |
| 	char	*assignments;	/* a string containing option assignments */
 | |
| {
 | |
| 	char	*name;		/* name of variable in assignments */
 | |
| 	char	*value;		/* value of the variable */
 | |
| 	char	*scan;		/* used for moving through strings */
 | |
| 	char	*build;		/* used for copying chars from "scan" */
 | |
| 	char	*prefix;	/* pointer to "neg" or "no" at front of a boolean */
 | |
| 	int	quote;		/* boolean: inside '"' quotes? */
 | |
| 	int	i, j;
 | |
| 
 | |
| #ifndef CRUNCH
 | |
| 	/* reset the upper limit of "window" option to lines-1 */
 | |
| 	*o_window = *o_lines - 1;
 | |
| #endif
 | |
| 
 | |
| 	/* for each assignment... */
 | |
| 	for (name = assignments; *name; )
 | |
| 	{
 | |
| 		/* skip whitespace */
 | |
| 		if (*name == ' ' || *name == '\t')
 | |
| 		{
 | |
| 			name++;
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		/* after the name, find the value (if any) */
 | |
| 		for (scan = name; isalnum(*scan); scan++)
 | |
| 		{
 | |
| 		}
 | |
| 		if (*scan == '=')
 | |
| 		{
 | |
| 			*scan++ = '\0';
 | |
| 			value = build = scan;
 | |
| 			for (quote = FALSE; *scan && (quote || !isspace(*scan)); scan++)
 | |
| 			{
 | |
| 				if (*scan == '"')
 | |
| 				{
 | |
| 					quote = !quote;
 | |
| 				}
 | |
| 				else if (*scan == '\\' && scan[1])
 | |
| 				{
 | |
| 					*build++ = *++scan;
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					*build++ = *scan;
 | |
| 				}
 | |
| 			}
 | |
| 			if (*scan)
 | |
| 				scan++;
 | |
| 			*build = '\0';
 | |
| 		}
 | |
| 		else /* no "=" so it is probably boolean... */
 | |
| 		{
 | |
| 			if (*scan)
 | |
| 			{
 | |
| 				*scan++ = '\0';
 | |
| 			}
 | |
| 			value = NULL;
 | |
| 			prefix = name;
 | |
| #ifndef CRUNCH
 | |
| 			if (!strcmp(name, "novice"))
 | |
| 				/* don't check for a "no" prefix */;
 | |
| 			else
 | |
| #endif
 | |
| 			if (prefix[0] == 'n' && prefix[1] == 'o')
 | |
| 				name += 2;
 | |
| 			else if (prefix[0] == 'n' && prefix[1] == 'e' && prefix[2] == 'g')
 | |
| 				name += 3;
 | |
| 		}
 | |
| 
 | |
| 		/* find the variable */
 | |
| 		for (i = 0;
 | |
| 		     opts[i].name && strcmp(opts[i].name, name) && strcmp(opts[i].nm, name);
 | |
| 		     i++)
 | |
| 		{
 | |
| 		}
 | |
| 
 | |
| 		/* change the variable */
 | |
| 		if (!opts[i].name)
 | |
| 		{
 | |
| 			msg("invalid option name \"%s\"", name);
 | |
| 		}
 | |
| 		else if ((opts[i].flags & CANSET) != CANSET)
 | |
| 		{
 | |
| 			msg("option \"%s\" can't be altered", name);
 | |
| 		}
 | |
| 		else if ((opts[i].flags & RCSET) != CANSET && nlines >= 1L)
 | |
| 		{
 | |
| 			msg("option \"%s\" can only be set in a %s file", name, EXRC);
 | |
| 		}
 | |
| 		else if (value)
 | |
| 		{
 | |
| 			switch (opts[i].type)
 | |
| 			{
 | |
| 			  case BOOL:
 | |
| 				msg("option \"[no]%s\" is boolean", name);
 | |
| 				break;
 | |
| 
 | |
| 			  case NUM:
 | |
| 				j = atoi(value);
 | |
| 				if (j == 0 && *value != '0')
 | |
| 				{
 | |
| 					msg("option \"%s\" must have a numeric value", name);
 | |
| 				}
 | |
| 				else if (j < opts[i].value[1] || j > (opts[i].value[2] & 0xff))
 | |
| 				{
 | |
| 					msg("option \"%s\" must have a value between %d and %d",
 | |
| 						name, opts[i].value[1], opts[i].value[2] & 0xff);
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					*opts[i].value = atoi(value);
 | |
| 					opts[i].flags |= SET;
 | |
| 				}
 | |
| 				break;
 | |
| 
 | |
| 			  case STR:
 | |
| 				strcpy(opts[i].value, value);
 | |
| 				opts[i].flags |= SET;
 | |
| 				break;
 | |
| 			}
 | |
| 			if (opts[i].flags & MR)
 | |
| 			{
 | |
| 				redraw(MARK_UNSET, FALSE);
 | |
| 			}
 | |
| #ifndef CRUNCH
 | |
| 			if (opts[i].flags & WSET)
 | |
| 			{
 | |
| 				wset = TRUE;
 | |
| 			}
 | |
| #endif
 | |
| 		}
 | |
| 		else /* valid option, no value */
 | |
| 		{
 | |
| 			if (opts[i].type == BOOL)
 | |
| 			{
 | |
| 				if (prefix == name)
 | |
| 					*opts[i].value = TRUE;
 | |
| 				else if (prefix[1] == 'o')
 | |
| 					*opts[i].value = FALSE;
 | |
| 				else
 | |
| 					*opts[i].value = !*opts[i].value;
 | |
| 
 | |
| 				opts[i].flags |= SET;
 | |
| 				if (opts[i].flags & MR)
 | |
| 				{
 | |
| 					redraw(MARK_UNSET, FALSE);
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				msg("option \"%s\" must be given a value", name);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/* move on to the next option */
 | |
| 		name = scan;
 | |
| 	}
 | |
| 
 | |
| 	/* special processing ... */
 | |
| 
 | |
| #ifndef CRUNCH
 | |
| 	/* if "novice" is set, then ":set report=1 showmode nomagic" */
 | |
| 	if (*o_novice)
 | |
| 	{
 | |
| 		*o_report = 1;
 | |
| # ifndef NO_SHOWMODE
 | |
| 		*o_smd = TRUE;
 | |
| # endif
 | |
| # ifndef NO_MAGIC
 | |
| 		*o_magic = FALSE;
 | |
| # endif
 | |
| 	}
 | |
| #endif
 | |
| 
 | |
| 	/* if "readonly" then set the READONLY flag for this file */
 | |
| 	if (*o_readonly)
 | |
| 	{
 | |
| 		setflag(file, READONLY);
 | |
| 	}
 | |
| 
 | |
| #ifndef NO_DIGRAPH
 | |
| 	/* re-initialize the ctype package */
 | |
| 	_ct_init(o_flipcase);
 | |
| #endif /* not NO_DIGRAPH */
 | |
| 
 | |
| 	/* copy o_lines and o_columns into LINES and COLS */
 | |
| 	LINES = (*o_lines & 255);
 | |
| 	COLS = (*o_columns & 255);
 | |
| }
 | 
