Skip to content

Commit

Permalink
patch 9.0.1359: too many "else if" statements in handling options
Browse files Browse the repository at this point in the history
Problem:    Too many "else if" statements in handling options.
Solution:   Add more functions for handling option changes. (Yegappan
            Lakshmanan, closes #12060)
  • Loading branch information
yegappan authored and brammool committed Feb 27, 2023
1 parent 30a8447 commit 5da901b
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 61 deletions.
17 changes: 8 additions & 9 deletions src/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -3088,11 +3088,10 @@ did_set_langmap(optset_T *args UNUSED)
}
if (to == NUL)
{
// TODO: Need to use errbuf argument for this error message
// and return it.
semsg(_(e_langmap_matching_character_missing_for_str),
transchar(from));
return NULL;
sprintf(args->os_errbuf,
_(e_langmap_matching_character_missing_for_str),
transchar(from));
return args->os_errbuf;
}

if (from >= 256)
Expand All @@ -3112,10 +3111,10 @@ did_set_langmap(optset_T *args UNUSED)
{
if (p[0] != ',')
{
// TODO: Need to use errbuf argument for this error
// message and return it.
semsg(_(e_langmap_extra_characters_after_semicolon_str), p);
return NULL;
sprintf(args->os_errbuf,
_(e_langmap_extra_characters_after_semicolon_str),
p);
return args->os_errbuf;
}
++p;
}
Expand Down
20 changes: 11 additions & 9 deletions src/optiondefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -939,7 +939,8 @@ static struct vimoption options[] =
#endif
(char_u *)0L} SCTX_INIT},
{"filetype", "ft", P_STRING|P_EXPAND|P_ALLOCED|P_VI_DEF|P_NOGLOB|P_NFNAME,
(char_u *)&p_ft, PV_FT, NULL,
(char_u *)&p_ft, PV_FT,
did_set_filetype_or_syntax,
{(char_u *)"", (char_u *)0L}
SCTX_INIT},
{"fillchars", "fcs", P_STRING|P_VI_DEF|P_RALL|P_ONECOMMA|P_NODUP,
Expand Down Expand Up @@ -1411,7 +1412,7 @@ static struct vimoption options[] =
(char_u *)&p_im, PV_NONE, did_set_insertmode,
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
{"isfname", "isf", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
(char_u *)&p_isf, PV_NONE, NULL,
(char_u *)&p_isf, PV_NONE, did_set_isopt,
{
#ifdef BACKSLASH_IN_FILENAME
// Excluded are: & and ^ are special in cmd.exe
Expand All @@ -1428,7 +1429,7 @@ static struct vimoption options[] =
#endif
(char_u *)0L} SCTX_INIT},
{"isident", "isi", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
(char_u *)&p_isi, PV_NONE, NULL,
(char_u *)&p_isi, PV_NONE, did_set_isopt,
{
#if defined(MSWIN)
(char_u *)"@,48-57,_,128-167,224-235",
Expand All @@ -1437,7 +1438,7 @@ static struct vimoption options[] =
#endif
(char_u *)0L} SCTX_INIT},
{"iskeyword", "isk", P_STRING|P_ALLOCED|P_VIM|P_COMMA|P_NODUP,
(char_u *)&p_isk, PV_ISK, NULL,
(char_u *)&p_isk, PV_ISK, did_set_isopt,
{
(char_u *)"@,48-57,_",
#if defined(MSWIN)
Expand All @@ -1447,7 +1448,7 @@ static struct vimoption options[] =
#endif
} SCTX_INIT},
{"isprint", "isp", P_STRING|P_VI_DEF|P_RALL|P_COMMA|P_NODUP,
(char_u *)&p_isp, PV_NONE, NULL,
(char_u *)&p_isp, PV_NONE, did_set_isopt,
{
#if defined(MSWIN) || defined(VMS)
(char_u *)"@,~-255",
Expand All @@ -1469,7 +1470,7 @@ static struct vimoption options[] =
SCTX_INIT},
{"keymap", "kmp", P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF|P_RSTAT|P_NFNAME|P_PRI_MKRC,
#ifdef FEAT_KEYMAP
(char_u *)&p_keymap, PV_KMAP, NULL,
(char_u *)&p_keymap, PV_KMAP, did_set_keymap,
{(char_u *)"", (char_u *)0L}
#else
(char_u *)NULL, PV_NONE, NULL,
Expand Down Expand Up @@ -2095,7 +2096,7 @@ static struct vimoption options[] =
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
{"rightleftcmd", "rlc", P_STRING|P_ALLOCED|P_VI_DEF|P_RWIN,
#ifdef FEAT_RIGHTLEFT
(char_u *)VAR_WIN, PV_RLC, NULL,
(char_u *)VAR_WIN, PV_RLC, did_set_rightleftcmd,
{(char_u *)"search", (char_u *)NULL}
#else
(char_u *)NULL, PV_NONE, NULL,
Expand Down Expand Up @@ -2419,7 +2420,7 @@ static struct vimoption options[] =
(char_u *)&p_swf, PV_SWF, did_set_swapfile,
{(char_u *)TRUE, (char_u *)0L} SCTX_INIT},
{"swapsync", "sws", P_STRING|P_VI_DEF,
(char_u *)&p_sws, PV_NONE, NULL,
(char_u *)&p_sws, PV_NONE, did_set_swapsync,
{(char_u *)"fsync", (char_u *)0L} SCTX_INIT},
{"switchbuf", "swb", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
(char_u *)&p_swb, PV_NONE, did_set_switchbuf,
Expand All @@ -2435,7 +2436,8 @@ static struct vimoption options[] =
SCTX_INIT},
{"syntax", "syn", P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB|P_NFNAME,
#ifdef FEAT_SYN_HL
(char_u *)&p_syn, PV_SYN, NULL,
(char_u *)&p_syn, PV_SYN,
did_set_filetype_or_syntax,
{(char_u *)"", (char_u *)0L}
#else
(char_u *)NULL, PV_NONE, NULL,
Expand Down
101 changes: 61 additions & 40 deletions src/optionstr.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ static char *(p_scl_values[]) = {"yes", "no", "auto", "number", NULL};
static char *(p_twt_values[]) = {"winpty", "conpty", "", NULL};
#endif
static char *(p_sloc_values[]) = {"last", "statusline", "tabline", NULL};
static char *(p_sws_values[]) = {"fsync", "sync", NULL};

static int check_opt_strings(char_u *val, char **values, int list);
static int opt_strings_flags(char_u *val, char **values, unsigned *flagp, int list);
Expand Down Expand Up @@ -761,15 +762,15 @@ did_set_breakindentopt(optset_T *args UNUSED)
* The 'isident' or the 'iskeyword' or the 'isprint' or the 'isfname' option is
* changed.
*/
static char *
did_set_isopt(int *did_chartab)
char *
did_set_isopt(optset_T *args)
{
// 'isident', 'iskeyword', 'isprint or 'isfname' option: refill g_chartab[]
// If the new option is invalid, use old value.
// 'lisp' option: refill g_chartab[] for '-' char.
if (init_chartab() == FAIL)
{
*did_chartab = TRUE; // need to restore it below
args->os_restore_chartab = TRUE;// need to restore the chartab.
return e_invalid_argument; // error in value
}

Expand Down Expand Up @@ -928,6 +929,15 @@ did_set_splitkeep(optset_T *args UNUSED)
return did_set_opt_strings(p_spk, p_spk_values, FALSE);
}

/*
* The 'swapsync' option is changed.
*/
char *
did_set_swapsync(optset_T *args UNUSED)
{
return did_set_opt_strings(p_sws, p_sws_values, FALSE);
}

/*
* The 'switchbuf' option is changed.
*/
Expand Down Expand Up @@ -1224,16 +1234,16 @@ did_set_imactivatekey(optset_T *args UNUSED)
}
#endif

#ifdef FEAT_KEYMAP
#if defined(FEAT_KEYMAP) || defined(PROTO)
/*
* The 'keymap' option is changed.
*/
static char *
did_set_keymap(char_u **varp, int opt_flags, int *value_checked)
char *
did_set_keymap(optset_T *args)
{
char *errmsg = NULL;

if (!valid_filetype(*varp))
if (!valid_filetype(args->os_varp))
errmsg = e_invalid_argument;
else
{
Expand All @@ -1250,7 +1260,7 @@ did_set_keymap(char_u **varp, int opt_flags, int *value_checked)

// Since we check the value, there is no need to set P_INSECURE,
// even when the value comes from a modeline.
*value_checked = TRUE;
args->os_value_checked = TRUE;
}

if (errmsg == NULL)
Expand All @@ -1270,7 +1280,7 @@ did_set_keymap(char_u **varp, int opt_flags, int *value_checked)
if (curbuf->b_p_imsearch == B_IMODE_LMAP)
curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
}
if ((opt_flags & OPT_LOCAL) == 0)
if ((args->os_flags & OPT_LOCAL) == 0)
{
set_iminsert_global();
set_imsearch_global();
Expand Down Expand Up @@ -2573,7 +2583,8 @@ did_set_cinoptions(optset_T *args UNUSED)
char *
did_set_lispoptions(optset_T *args)
{
if (*args->os_varp != NUL && STRCMP(args->os_varp, "expr:0") != 0
if (*args->os_varp != NUL
&& STRCMP(args->os_varp, "expr:0") != 0
&& STRCMP(args->os_varp, "expr:1") != 0)
return e_invalid_argument;

Expand All @@ -2594,24 +2605,36 @@ did_set_renderoptions(optset_T *args UNUSED)
}
#endif

#if defined(FEAT_RIGHTLEFT) || defined(PROTO)
/*
* The 'rightleftcmd' option is changed.
*/
char *
did_set_rightleftcmd(optset_T *args)
{
// Currently only "search" is a supported value.
if (*args->os_varp != NUL && STRCMP(args->os_varp, "search") != 0)
return e_invalid_argument;

return NULL;
}
#endif

/*
* The 'filetype' or the 'syntax' option is changed.
*/
static char *
did_set_filetype_or_syntax(
char_u **varp,
char_u *oldval,
int *value_checked,
int *value_changed)
char *
did_set_filetype_or_syntax(optset_T *args)
{
if (!valid_filetype(*varp))
if (!valid_filetype(args->os_varp))
return e_invalid_argument;

*value_changed = STRCMP(oldval, *varp) != 0;
args->os_value_changed =
STRCMP(args->os_oldval.string, args->os_varp) != 0;

// Since we check the value, there is no need to set P_INSECURE,
// even when the value comes from a modeline.
*value_checked = TRUE;
args->os_value_checked = TRUE;

return NULL;
}
Expand Down Expand Up @@ -3008,7 +3031,7 @@ did_set_string_option(
// need to set P_INSECURE
{
char *errmsg = NULL;
int did_chartab = FALSE;
int restore_chartab = FALSE;
char_u **gvarp;
long_u free_oldval = (get_option_flags(opt_idx) & P_ALLOCED);
int value_changed = FALSE;
Expand Down Expand Up @@ -3037,31 +3060,37 @@ did_set_string_option(
args.os_flags = opt_flags;
args.os_oldval.string = oldval;
args.os_newval.string = value;
args.os_value_checked = FALSE;
args.os_value_changed = FALSE;
args.os_restore_chartab = FALSE;
args.os_errbuf = errbuf;
// Invoke the option specific callback function to validate and apply
// the new option value.
errmsg = did_set_cb(&args);

#ifdef FEAT_EVAL
// When processing the '*expr' options (e.g. diffexpr, foldexpr, etc.),
// the did_set_cb() function may modify '*varp'.
// The '*expr' option (e.g. diffexpr, foldexpr, etc.), callback
// functions may modify '*varp'.
if (errmsg == NULL && is_expr_option(varp, gvarp))
*varp = args.os_varp;
#endif
// The 'filetype' and 'syntax' option callback functions may change
// the os_value_changed field.
value_changed = args.os_value_changed;
// The 'keymap', 'filetype' and 'syntax' option callback functions
// may change the os_value_checked field.
*value_checked = args.os_value_checked;
// The 'isident', 'iskeyword', 'isprint' and 'isfname' options may
// change the character table. On failure, this needs to be restored.
restore_chartab = args.os_restore_chartab;
}
else if (varp == &T_NAME) // 'term'
errmsg = did_set_term(&opt_idx, &free_oldval);
else if ( varp == &p_isi // 'isident'
|| varp == &(curbuf->b_p_isk) // 'iskeyword'
|| varp == &p_isp // 'isprint'
|| varp == &p_isf) // 'isfname'
errmsg = did_set_isopt(&did_chartab);
else if ( varp == &p_enc // 'encoding'
|| gvarp == &p_fenc // 'fileencoding'
|| varp == &p_tenc // 'termencoding'
|| gvarp == &p_menc) // 'makeencoding'
errmsg = did_set_encoding(varp, gvarp, opt_flags);
#ifdef FEAT_KEYMAP
else if (varp == &curbuf->b_p_keymap) // 'keymap'
errmsg = did_set_keymap(varp, opt_flags, value_checked);
#endif
else if ( varp == &p_lcs // global 'listchars'
|| varp == &p_fcs) // global 'fillchars'
errmsg = did_set_global_listfillchars(varp, opt_flags);
Expand All @@ -3072,22 +3101,14 @@ did_set_string_option(
// terminal options
else if (istermoption_idx(opt_idx) && full_screen)
did_set_term_option(varp, &did_swaptcap);
else if (gvarp == &p_ft) // 'filetype'
errmsg = did_set_filetype_or_syntax(varp, oldval, value_checked,
&value_changed);
#ifdef FEAT_SYN_HL
else if (gvarp == &p_syn) // 'syntax'
errmsg = did_set_filetype_or_syntax(varp, oldval, value_checked,
&value_changed);
#endif

// If an error is detected, restore the previous value.
if (errmsg != NULL)
{
free_string_option(*varp);
*varp = oldval;
// When resetting some values, need to act on it.
if (did_chartab)
if (restore_chartab)
(void)init_chartab();
if (varp == &p_hl)
(void)highlight_changed();
Expand Down
5 changes: 5 additions & 0 deletions src/proto/optionstr.pro
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ char *set_string_option(int opt_idx, char_u *value, int opt_flags, char *errbuf)
char *did_set_backupcopy(optset_T *args);
char *did_set_backupext_or_patchmode(optset_T *args);
char *did_set_breakindentopt(optset_T *args);
char *did_set_isopt(optset_T *args);
char *did_set_helpfile(optset_T *args);
char *did_set_colorcolumn(optset_T *args);
char *did_set_cursorlineopt(optset_T *args);
Expand All @@ -23,6 +24,7 @@ char *did_set_scrollopt(optset_T *args);
char *did_set_selectmode(optset_T *args);
char *did_set_showcmdloc(optset_T *args);
char *did_set_splitkeep(optset_T *args);
char *did_set_swapsync(optset_T *args);
char *did_set_switchbuf(optset_T *args);
char *did_set_sessionoptions(optset_T *args);
char *did_set_viewoptions(optset_T *args);
Expand All @@ -36,6 +38,7 @@ char *did_set_eadirection(optset_T *args);
char *did_set_eventignore(optset_T *args);
char *did_set_printencoding(optset_T *args);
char *did_set_imactivatekey(optset_T *args);
char *did_set_keymap(optset_T *args);
char *did_set_fileformat(optset_T *args);
char *did_set_fileformats(optset_T *args);
char *did_set_cryptkey(optset_T *args);
Expand Down Expand Up @@ -96,6 +99,8 @@ char *did_set_cscopequickfix(optset_T *args);
char *did_set_cinoptions(optset_T *args);
char *did_set_lispoptions(optset_T *args);
char *did_set_renderoptions(optset_T *args);
char *did_set_rightleftcmd(optset_T *args);
char *did_set_filetype_or_syntax(optset_T *args);
char *did_set_termwinkey(optset_T *args);
char *did_set_termwinsize(optset_T *args);
char *did_set_termwintype(optset_T *args);
Expand Down
11 changes: 11 additions & 0 deletions src/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -4820,6 +4820,17 @@ typedef struct
// Currently only used for boolean options.
int os_doskip;

// Option value was checked to be safe, no need to set P_INSECURE
// Used for the 'keymap', 'filetype' and 'syntax' options.
int os_value_checked;
// Option value changed. Used for the 'filetype' and 'syntax' options.
int os_value_changed;

// Used by the 'isident', 'iskeyword', 'isprint' and 'isfname' options.
// Set to TRUE if the character table is modified when processing the
// option and need to be restored because of a failure.
int os_restore_chartab;

// If the value specified for an option is not valid and the error message
// is parameterized, then the "os_errbuf" buffer is used to store the error
// message (when it is not NULL).
Expand Down

0 comments on commit 5da901b

Please sign in to comment.