refactor(option.c): factor out string option special case handling

This commit is contained in:
Lewis Russell 2023-01-26 11:17:36 +00:00
parent 068151f5c6
commit 77a0ce1d9b

View File

@ -817,6 +817,78 @@ static void do_set_num(int opt_idx, int opt_flags, char **argp, int nextchar, co
errbuf, errbuflen, opt_flags);
}
// Handle some special cases with string option values
static void munge_string_opt_val(char **varp, char **oldval, char **const origval,
char_u **const origval_l, char_u **const origval_g,
char **const argp, char *const whichwrap, size_t whichwraplen,
char **const save_argp)
{
// Set 'keywordprg' to ":help" if an empty
// value was passed to :set by the user.
if (varp == &p_kp && (**argp == NUL || **argp == ' ')) {
*save_argp = *argp;
*argp = ":help";
} else if (varp == &p_bs && ascii_isdigit(**(char_u **)varp)) {
// Convert 'backspace' number to string, for
// adding, prepending and removing string.
const int i = getdigits_int(varp, true, 0);
switch (i) {
case 0:
*varp = empty_option;
break;
case 1:
*varp = xstrdup("indent,eol");
break;
case 2:
*varp = xstrdup("indent,eol,start");
break;
case 3:
*varp = xstrdup("indent,eol,nostop");
break;
}
xfree(*oldval);
if (*origval == *oldval) {
*origval = *varp;
}
if (*origval_l == (char_u *)(*oldval)) {
*origval_l = *(char_u **)varp;
}
if (*origval_g == (char_u *)(*oldval)) {
*origval_g = *(char_u **)varp;
}
*oldval = *varp;
} else if (varp == &p_ww && ascii_isdigit(**argp)) {
// Convert 'whichwrap' number to string, for backwards compatibility
// with Vim 3.0.
*whichwrap = NUL;
int i = getdigits_int(argp, true, 0);
if (i & 1) {
xstrlcat(whichwrap, "b,", whichwraplen);
}
if (i & 2) {
xstrlcat(whichwrap, "s,", whichwraplen);
}
if (i & 4) {
xstrlcat(whichwrap, "h,l,", whichwraplen);
}
if (i & 8) {
xstrlcat(whichwrap, "<,>,", whichwraplen);
}
if (i & 16) {
xstrlcat(whichwrap, "[,],", whichwraplen);
}
if (*whichwrap != NUL) { // remove trailing ,
whichwrap[strlen(whichwrap) - 1] = NUL;
}
*save_argp = *argp;
*argp = whichwrap;
} else if (**argp == '>' && (varp == &p_dir || varp == &p_bdir)) {
// Remove '>' before 'dir' and 'bdir', for backwards compatibility with
// version 3.0
(*argp)++;
}
}
/// Part of do_set() for string options.
static void do_set_string(int opt_idx, int opt_flags, char **argp, int nextchar, set_op_T op_arg,
uint32_t flags, char *varp_arg, char *errbuf, size_t errbuflen,
@ -884,70 +956,8 @@ static void do_set_string(int opt_idx, int opt_flags, char **argp, int nextchar,
} else {
arg++; // jump to after the '=' or ':'
// Set 'keywordprg' to ":help" if an empty
// value was passed to :set by the user.
if (varp == (char *)&p_kp && (*arg == NUL || *arg == ' ')) {
save_arg = arg;
arg = ":help";
} else if (varp == (char *)&p_bs && ascii_isdigit(**(char_u **)varp)) {
// Convert 'backspace' number to string, for
// adding, prepending and removing string.
int i = getdigits_int((char **)varp, true, 0);
switch (i) {
case 0:
*(char **)varp = empty_option;
break;
case 1:
*(char_u **)varp = (char_u *)xstrdup("indent,eol");
break;
case 2:
*(char_u **)varp = (char_u *)xstrdup("indent,eol,start");
break;
case 3:
*(char_u **)varp = (char_u *)xstrdup("indent,eol,nostop");
break;
}
xfree(oldval);
if (origval == oldval) {
origval = *(char **)varp;
}
if (origval_l == (char_u *)oldval) {
origval_l = *(char_u **)varp;
}
if (origval_g == (char_u *)oldval) {
origval_g = *(char_u **)varp;
}
oldval = *(char **)varp;
} else if (varp == (char *)&p_ww && ascii_isdigit(*arg)) {
// Convert 'whichwrap' number to string, for backwards compatibility
// with Vim 3.0.
*whichwrap = NUL;
int i = getdigits_int(&arg, true, 0);
if (i & 1) {
xstrlcat(whichwrap, "b,", sizeof(whichwrap));
}
if (i & 2) {
xstrlcat(whichwrap, "s,", sizeof(whichwrap));
}
if (i & 4) {
xstrlcat(whichwrap, "h,l,", sizeof(whichwrap));
}
if (i & 8) {
xstrlcat(whichwrap, "<,>,", sizeof(whichwrap));
}
if (i & 16) {
xstrlcat(whichwrap, "[,],", sizeof(whichwrap));
}
if (*whichwrap != NUL) { // remove trailing ,
whichwrap[strlen(whichwrap) - 1] = NUL;
}
save_arg = arg;
arg = whichwrap;
} else if (*arg == '>' && (varp == (char *)&p_dir || varp == (char *)&p_bdir)) {
// Remove '>' before 'dir' and 'bdir', for backwards compatibility with
// version 3.0
arg++;
}
munge_string_opt_val((char **)varp, &oldval, &origval, &origval_l, &origval_g, &arg,
whichwrap, sizeof(whichwrap), &save_arg);
// Copy the new string into allocated memory.
// Can't use set_string_option_direct(), because we need to remove the