home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
v
/
vim_src.zip
/
PARAM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-12
|
15KB
|
525 lines
/* vi:ts=4:sw=4
*
* VIM - Vi IMitation
*
* Code Contributions By: Bram Moolenaar mool@oce.nl
* Tim Thompson twitch!tjt
* Tony Andrews onecom!wldrdg!tony
* G. R. (Fred) Walter watmath!watcgl!grwalter
*/
/*
* Code to handle user-settable parameters. This is all pretty much table-
* driven. To add a new parameter, put it in the params array, and add a
* variable for it in param.h. If it's a numeric parameter, add any necessary
* bounds checks to doset().
*/
#include "vim.h"
#include "globals.h"
#include "proto.h"
#include "param.h"
struct param
{
char *fullname; /* full parameter name */
char *shortname; /* permissible abbreviation */
int flags; /* see below */
char *var; /* pointer to variable */
};
/*
* Flags
*/
#define P_BOOL 0x01 /* the parameter is boolean */
#define P_NUM 0x02 /* the parameter is numeric */
#define P_STRING 0x04 /* the parameter is a string */
#define P_CHANGED 0x08 /* the parameter has been changed */
/*
* The param structure is initialized here.
* The order of the parameters should be alfabetic
*/
struct param params[] =
{
{"autoindent", "ai", P_BOOL, (char *)&p_ai},
/* {"autoprint", "ap", P_BOOL, (char *)&p_ap}, */
{"autowrite", "aw", P_BOOL, (char *)&p_aw},
{"backspace", "bs", P_NUM, (char *)&p_bs},
{"backup", "bk", P_BOOL, (char *)&p_bk},
#ifdef UNIX
{"backupdir", "bdir", P_STRING, (char *)&p_bdir},
#endif
/* {"beautify", "bf", P_BOOL, (char *)&p_bf}, */
{"columns", "co", P_NUM, (char *)&Columns},
#ifdef DIGRAPHS
{"digraph", "dg", P_BOOL, (char *)&p_dg},
#endif /* DIGRAPHS */
{"directory", "dir", P_STRING, (char *)&p_dir},
{"equalprg", "ep", P_STRING, (char *)&p_ep},
{"errorbells", "eb", P_BOOL, (char *)&p_eb},
{"errorfile", "ef", P_STRING, (char *)&p_ef},
{"expandtab", "et", P_BOOL, (char *)&p_et},
{"graphic", "gr", P_BOOL, (char *)&p_gr},
/* {"hardtabs", "ht", P_NUM, (char *)&p_ht}, */
{"helpfile", "hf", P_STRING, (char *)&p_hf},
{"history", "hi", P_NUM, (char *)&p_hi},
{"ignorecase", "ic", P_BOOL, (char *)&p_ic},
{"insertmode", "im", P_BOOL, (char *)&p_im},
{"joinspaces", "js", P_BOOL, (char *)&p_js},
{"keywordprg", "kp", P_STRING, (char *)&p_kp},
{"lines", NULL, P_NUM, (char *)&Rows},
/* {"lisp", NULL, P_BOOL (char *)&p_lisp}, */
{"list", NULL, P_BOOL, (char *)&p_list},
{"magic", NULL, P_BOOL, (char *)&p_magic},
{"modelines", "ml", P_NUM, (char *)&p_ml},
{"number", "nu", P_BOOL, (char *)&p_nu},
/* {"open", NULL, P_BOOL, (char *)&p_open}, */
/* {"optimize", "opt", P_BOOL, (char *)&p_opt}, */
{"paragraphs", "para", P_STRING, (char *)&p_para},
/* {"prompt", NULL, P_BOOL, (char *)&p_prompt}, */
{"readonly", "ro", P_BOOL, (char *)&p_ro},
/* {"redraw", NULL, P_BOOL, (char *)&p_redraw}, */
{"remap", NULL, P_BOOL, (char *)&p_remap},
{"repdel", "rd", P_BOOL, (char *)&p_rd},
{"report", NULL, P_NUM, (char *)&p_report},
{"ruler", "ru", P_BOOL, (char *)&p_ru},
{"scroll", NULL, P_NUM, (char *)&p_scroll},
{"scrolljump", "sj", P_NUM, (char *)&p_sj},
{"sections", NULL, P_STRING, (char *)&p_sections},
{"shell", "sh", P_STRING, (char *)&p_sh},
{"shelltype", "st", P_NUM, (char *)&p_st},
{"shiftround", "sr", P_BOOL, (char *)&p_sr},
{"shiftwidth", "sw", P_NUM, (char *)&p_sw},
{"showcmd", "sc", P_BOOL, (char *)&p_sc},
{"showmatch", "sm", P_BOOL, (char *)&p_sm},
{"showmode", "mo", P_BOOL, (char *)&p_mo},
/* {"slowopen", "slow", P_BOOL, (char *)&p_slow}, */
{"smartindent", "si", P_BOOL, (char *)&p_si},
{"suffixes", "su", P_STRING, (char *)&p_su},
{"tabstop", "ts", P_NUM, (char *)&p_ts},
{"taglength", "tl", P_NUM, (char *)&p_tl},
{"tags", NULL, P_STRING, (char *)&p_tags},
{"term", NULL, P_STRING, (char *)&term_strings.t_name},
{"terse", NULL, P_BOOL, (char *)&p_terse},
#ifdef MSDOS
{"textmode", "tx", P_BOOL, (char *)&p_tx},
#endif
{"textwidth", "tw", P_NUM, (char *)&p_tw},
{"tildeop", "to", P_BOOL, (char *)&p_to},
{"timeout", NULL, P_BOOL, (char *)&p_timeout},
{"undolevels", "ul", P_NUM, (char *)&p_ul},
{"updatecount", "uc", P_NUM, (char *)&p_uc},
{"updatetime", "ut", P_NUM, (char *)&p_ut},
{"visualbell", "vb", P_BOOL, (char *)&p_vb},
{"warn", NULL, P_BOOL, (char *)&p_warn},
/* {"window", NULL, P_NUM, (char *)&p_window}, */
/* {"w300", NULL, P_NUM, (char *)&p_w300}, */
/* {"w1200", NULL, P_NUM, (char *)&p_w1200}, */
/* {"w9600", NULL, P_NUM, (char *)&p_w9600}, */
{"wrapscan", "ws", P_BOOL, (char *)&p_ws},
{"wrapmargin", "wm", P_NUM, (char *)&p_wm},
{"writeany", "wa", P_BOOL, (char *)&p_wa},
{"writebackup", "wb", P_BOOL, (char *)&p_wb},
{"yankendofline", "ye", P_BOOL, (char *)&p_ye},
/* terminal output codes */
{"t_el", NULL, P_STRING, (char *)&term_strings.t_el},
{"t_il", NULL, P_STRING, (char *)&term_strings.t_il},
{"t_cil", NULL, P_STRING, (char *)&term_strings.t_cil},
{"t_dl", NULL, P_STRING, (char *)&term_strings.t_dl},
{"t_cdl", NULL, P_STRING, (char *)&term_strings.t_cdl},
{"t_ed", NULL, P_STRING, (char *)&term_strings.t_ed},
{"t_ci", NULL, P_STRING, (char *)&term_strings.t_ci},
{"t_cv", NULL, P_STRING, (char *)&term_strings.t_cv},
{"t_tp", NULL, P_STRING, (char *)&term_strings.t_tp},
{"t_ti", NULL, P_STRING, (char *)&term_strings.t_ti},
{"t_cm", NULL, P_STRING, (char *)&term_strings.t_cm},
{"t_sr", NULL, P_STRING, (char *)&term_strings.t_sr},
{"t_cri", NULL, P_STRING, (char *)&term_strings.t_cri},
{"t_vb", NULL, P_STRING, (char *)&term_strings.t_vb},
{"t_ks", NULL, P_STRING, (char *)&term_strings.t_ks},
{"t_ke", NULL, P_STRING, (char *)&term_strings.t_ke},
/* terminal key codes */
{"t_ku", NULL, P_STRING, (char *)&term_strings.t_ku},
{"t_kd", NULL, P_STRING, (char *)&term_strings.t_kd},
{"t_kr", NULL, P_STRING, (char *)&term_strings.t_kr},
{"t_kl", NULL, P_STRING, (char *)&term_strings.t_kl},
{"t_sku", NULL, P_STRING, (char *)&term_strings.t_sku},
{"t_skd", NULL, P_STRING, (char *)&term_strings.t_skd},
{"t_skr", NULL, P_STRING, (char *)&term_strings.t_skr},
{"t_skl", NULL, P_STRING, (char *)&term_strings.t_skl},
{"t_f1", NULL, P_STRING, (char *)&term_strings.t_f1},
{"t_f2", NULL, P_STRING, (char *)&term_strings.t_f2},
{"t_f3", NULL, P_STRING, (char *)&term_strings.t_f3},
{"t_f4", NULL, P_STRING, (char *)&term_strings.t_f4},
{"t_f5", NULL, P_STRING, (char *)&term_strings.t_f5},
{"t_f6", NULL, P_STRING, (char *)&term_strings.t_f6},
{"t_f7", NULL, P_STRING, (char *)&term_strings.t_f7},
{"t_f8", NULL, P_STRING, (char *)&term_strings.t_f8},
{"t_f9", NULL, P_STRING, (char *)&term_strings.t_f9},
{"t_f10", NULL, P_STRING, (char *)&term_strings.t_f10},
{"t_sf1", NULL, P_STRING, (char *)&term_strings.t_sf1},
{"t_sf2", NULL, P_STRING, (char *)&term_strings.t_sf2},
{"t_sf3", NULL, P_STRING, (char *)&term_strings.t_sf3},
{"t_sf4", NULL, P_STRING, (char *)&term_strings.t_sf4},
{"t_sf5", NULL, P_STRING, (char *)&term_strings.t_sf5},
{"t_sf6", NULL, P_STRING, (char *)&term_strings.t_sf6},
{"t_sf7", NULL, P_STRING, (char *)&term_strings.t_sf7},
{"t_sf8", NULL, P_STRING, (char *)&term_strings.t_sf8},
{"t_sf9", NULL, P_STRING, (char *)&term_strings.t_sf9},
{"t_sf10", NULL, P_STRING, (char *)&term_strings.t_sf10},
{"t_help", NULL, P_STRING, (char *)&term_strings.t_help},
{"t_undo", NULL, P_STRING, (char *)&term_strings.t_undo},
{NULL, NULL, 0, NULL} /* end marker */
};
static void showparams __ARGS((int));
static void showonep __ARGS((struct param *));
static int istermparam __ARGS((struct param *));
/*
* Initialize the shell parameter and scroll size.
*/
void
set_init()
{
char *p;
if ((p = getenv("SHELL")) != NULL)
p_sh = strsave(p);
p_scroll = (Rows >> 1);
}
void
doset(arg)
char *arg; /* parameter string */
{
register int i;
char *s;
int prefix; /* 0: nothing, 1: "no", 2: "inv" in front of name */
int nextchar;
int len = 0;
int flags;
int olduc = p_uc; /* remember old update count */
if (*arg == NUL)
{
showparams(0);
return;
}
while (*arg) /* loop to process all parameters */
{
if (strncmp(arg, "all", (size_t)3) == 0)
showparams(1);
else if (strncmp(arg, "termcap", (size_t)7) == 0)
showparams(2);
else
{
prefix = 1;
if (strncmp(arg, "no", (size_t)2) == 0)
{
prefix = 0;
arg += 2;
}
else if (strncmp(arg, "inv", (size_t)3) == 0)
{
prefix = 2;
arg += 3;
}
for (i = 0; (s = params[i].fullname) != NULL; i++)
{
if (strncmp(arg, s, (size_t)(len = strlen(s))) == 0) /* match full name */
break;
}
if (s == NULL)
{
for (i = 0; params[i].fullname != NULL; i++)
{
s = params[i].shortname;
if (s != NULL && strncmp(arg, s, (size_t)(len = strlen(s))) == 0) /* match short name */
break;
s = NULL;
}
}
if (s == NULL) /* found a mismatch: skip the rest */
{
emsg(e_unrset);
break;
}
flags = params[i].flags;
nextchar = arg[len];
/*
* allow '=' and ':' as MSDOS command.com allows only one
* '=' character per "set" command line. grrr. (jw)
*/
if (nextchar == '?' ||
((nextchar != '=' && nextchar != ':') &&
!(flags & P_BOOL)))
{ /* print value */
gotocmdline(TRUE, NUL);
showonep(¶ms[i]);
}
else if (nextchar != NUL && strchr("=: \t", nextchar) == NULL)
{
emsg(e_setparam);
break;
}
else if (flags & P_BOOL) /* boolean */
{
if (nextchar == '=' || nextchar == ':')
{
emsg(e_setparam);
break;
}
if (prefix == 2)
*(int *)(params[i].var) ^= 1; /* invert it */
else
*(int *)(params[i].var) = prefix;
}
else /* numeric or string */
{
if ((nextchar != '=' && nextchar != ':') || prefix != 1)
{
emsg(e_setparam);
break;
}
if (flags & P_NUM) /* numeric */
{
len = atoi(arg + len + 1);
if ((long *)params[i].var == &p_wm) /* wrapmargin is translated into textlength */
{
if (len >= Columns)
len = Columns - 1;
p_tw = Columns - len;
}
*(long *)(params[i].var) = len;
}
else /* string */
{
arg += len + 1;
s = alloc((unsigned)(strlen(arg) + 1)); /* get a bit too much */
if (s == NULL)
break;
if (flags & P_CHANGED)
free(*(char **)(params[i].var));
*(char **)(params[i].var) = s;
/* copy the string */
while (*arg && *arg != ' ' && *arg != '\t')
{
if (*arg == '\\' && *(arg + 1)) /* skip over escaped chars */
++arg;
*s++ = *arg++;
}
*s = NUL;
/*
* options that need some action
* to perform when changed (jw)
*/
if (params[i].var == (char *)&term_strings.t_name)
set_term(term_strings.t_name);
else if (istermparam(¶ms[i]))
ttest(FALSE);
}
}
params[i].flags |= P_CHANGED;
}
skiptospace(&arg); /* skip to next white space */
skipspace(&arg); /* skip spaces */
}
/*
* Check the bounds for numeric parameters here
*/
if (p_ts <= 0 || p_ts > 16)
{
emsg(e_tabsize);
p_ts = 8;
}
if (p_scroll <= 0 || p_scroll > Rows)
{
emsg(e_scroll);
p_scroll = Rows >> 1;
}
if (p_sj < 0 || p_sj >= Rows)
{
emsg(e_scroll);
p_sj = 1;
}
if (p_ul < 0)
{
emsg(e_positive);
p_ul = 100;
}
if (p_uc < 0)
{
emsg(e_positive);
p_uc = 100;
}
if (p_uc == 0 && olduc != 0) /* p_uc changed from on to off */
stopscript();
if (p_uc > 0 && olduc == 0) /* p_uc changed from off to on */
startscript();
#ifdef MSDOS
textfile(p_tx);
#endif
if (p_ut < 0)
{
emsg(e_positive);
p_ut = 2000;
}
/*
* Update the screen in case we changed something like "tabstop" or
* "lines" or "list" that will change its appearance.
*/
updateScreen(NOT_VALID);
}
/*
* if 'all' == 0: show changed parameters
* if 'all' == 1: show all normal parameters
* if 'all' == 2: show all terminal parameters
*/
static void
showparams(all)
int all;
{
struct param *p;
int col = 0;
int inc;
int isterm;
gotocmdline(TRUE, NUL);
outstrn("Parameters:\n");
settmode(0); /* set cooked mode so output can be halted */
for (p = ¶ms[0]; p->fullname != NULL; p++)
{
isterm = istermparam(p);
if ((all == 2 && isterm) ||
(all == 1 && !isterm) ||
(all == 0 && (p->flags & P_CHANGED)))
{
if ((p->flags & P_STRING) && *(char **)(p->var) != NULL)
inc = strlen(p->fullname) + strsize(*(char **)(p->var)) + 1;
else
inc = 1;
if (col + inc >= Columns)
{
outchar('\n');
col = 0;
}
showonep(p);
col += inc;
col += 19 - col % 19;
if (col < Columns - 19)
windgoto((int)Rows - 1, col); /* make columns */
else
{
col = 0;
outchar('\n');
}
flushbuf();
}
}
if (col)
outchar('\n');
settmode(1);
wait_return(TRUE);
}
static void
showonep(p)
struct param *p;
{
char buf[64];
if ((p->flags & P_BOOL) && !*(int *)(p->var))
outstrn("no");
outstrn(p->fullname);
if (!(p->flags & P_BOOL))
{
outchar('=');
if (p->flags & P_NUM)
{
sprintf(buf, "%ld", *(long *)(p->var));
outstrn(buf);
}
else if (*(char **)(p->var) != NULL)
outtrans(*(char **)(p->var), -1);
}
}
/*
* Write modified parameters as set command to a file.
* Return 1 on error.
*/
int
makeset(fd)
FILE *fd;
{
struct param *p;
char *s;
int e;
for (p = ¶ms[0]; p->fullname != NULL; p++)
if (p->flags & P_CHANGED)
{
if (p->flags & P_BOOL)
e = fprintf(fd, "set %s%s\n", *(int *)(p->var) ? "" : "no", p->fullname);
else if (p->flags & P_NUM)
e = fprintf(fd, "set %s=%ld\n", p->fullname, *(long *)(p->var));
else
{
fprintf(fd, "set %s=", p->fullname);
s = *(char **)(p->var);
if (s != NULL)
for ( ; *s; ++s)
{
if (*s < ' ' || *s > '~')
putc(CTRL('V'), fd);
putc(*s, fd);
}
e = putc('\n', fd);
}
if (e < 0)
return 1;
}
return 0;
}
/*
* Clear all the terminal parameters.
* If the parameter has been changed, free the allocated memory.
* Reset the "changed" flag, so the new value will not be freed.
*/
void
clear_termparam()
{
struct param *p;
for (p = ¶ms[0]; p->fullname != NULL; p++)
if (istermparam(p))
{
if (p->flags & P_CHANGED)
free(*(char **)(p->var));
*(char **)(p->var) = NULL;
p->flags &= ~P_CHANGED;
}
}
static int
istermparam(p)
struct param *p;
{
return (p->fullname[0] == 't' && p->fullname[1] == '_');
}