option: Handle NULL string in set_option_value

This commit is contained in:
ZyX
2016-05-15 22:20:33 +03:00
parent f2f9ab6f35
commit 554005ea9a

View File

@@ -2314,43 +2314,43 @@ set_string_option_global (
} }
} }
/* /// Set a string option to a new value, handling the effects
* Set a string option to a new value, and handle the effects. ///
* /// @param[in] opt_idx Option to set.
* Returns NULL on success or error message on error. /// @param[in] value New value.
*/ /// @param[in] opt_flags Option flags: expected to contain #OPT_LOCAL and/or
static char_u * /// #OPT_GLOBAL.
set_string_option ( ///
int opt_idx, /// @return NULL on success, error message on error.
char_u *value, static char *set_string_option(const int opt_idx, const char *const value,
int opt_flags /* OPT_LOCAL and/or OPT_GLOBAL */ const int opt_flags)
) FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_WARN_UNUSED_RESULT
{ {
char_u *s; if (options[opt_idx].var == NULL) { // don't set hidden option
char_u **varp;
char_u *oldval;
char *saved_oldval = NULL;
char_u *r = NULL;
if (options[opt_idx].var == NULL) /* don't set hidden option */
return NULL; return NULL;
s = vim_strsave(value);
varp = (char_u **)get_varp_scope(&(options[opt_idx]),
(opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
? (((int)options[opt_idx].indir & PV_BOTH)
? OPT_GLOBAL : OPT_LOCAL)
: opt_flags);
oldval = *varp;
*varp = s;
if (!starting) {
saved_oldval = xstrdup((char *) oldval);
} }
if ((r = did_set_string_option(opt_idx, varp, (int)true, oldval, NULL, char *const s = xstrdup(value);
opt_flags)) == NULL) char **const varp = (char **)get_varp_scope(
did_set_option(opt_idx, opt_flags, TRUE); &(options[opt_idx]),
((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
? (((int)options[opt_idx].indir & PV_BOTH)
? OPT_GLOBAL : OPT_LOCAL)
: opt_flags));
char *const oldval = *varp;
*varp = s;
char *saved_oldval = NULL;
if (!starting) {
saved_oldval = xstrdup(oldval);
}
char *r = NULL;
if ((r = (char *)did_set_string_option(opt_idx, (char_u **)varp, (int)true,
(char_u *)oldval, NULL, opt_flags))
== NULL) {
did_set_option(opt_idx, opt_flags, true);
}
// call autocommand after handling side effects // call autocommand after handling side effects
if (saved_oldval != NULL) { if (saved_oldval != NULL) {
@@ -4655,26 +4655,28 @@ set_option_value (
EMSG(_(e_sandbox)); EMSG(_(e_sandbox));
return NULL; return NULL;
} }
if (flags & P_STRING) if (flags & P_STRING) {
return set_string_option(opt_idx, string, opt_flags); const char *s = (char *) string;
else { if (s == NULL) {
s = "";
}
return (char_u *)set_string_option(opt_idx, s, opt_flags);
} else {
varp = get_varp_scope(&(options[opt_idx]), opt_flags); varp = get_varp_scope(&(options[opt_idx]), opt_flags);
if (varp != NULL) { /* hidden option is not changed */ if (varp != NULL) { /* hidden option is not changed */
if (number == 0 && string != NULL) { if (number == 0 && string != NULL) {
int idx; int idx;
/* Either we are given a string or we are setting option // Either we are given a string or we are setting option
* to zero. */ // to zero.
for (idx = 0; string[idx] == '0'; ++idx) for (idx = 0; string[idx] == '0'; idx++) {}
;
if (string[idx] != NUL || idx == 0) { if (string[idx] != NUL || idx == 0) {
/* There's another character after zeros or the string // There's another character after zeros or the string
* is empty. In both cases, we are trying to set a // is empty. In both cases, we are trying to set a
* num option using a string. */ // num option using a string.
EMSG3(_("E521: Number required: &%s = '%s'"), EMSG3(_("E521: Number required: &%s = '%s'"),
name, string); name, string);
return NULL; /* do nothing as we hit an error */ return NULL; // do nothing as we hit an error
} }
} }
if (flags & P_NUM) if (flags & P_NUM)