aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/option.c146
1 files changed, 77 insertions, 69 deletions
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 716fd3775a..ffceeb6a5a 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -2981,181 +2981,189 @@ static const char *check_num_option_bounds(long *pp, long old_value, long old_Ro
return errmsg;
}
-/// Set the value of a number option, taking care of side effects
-///
-/// @param[in] opt_idx Option index in options[] table.
-/// @param[out] varp Pointer to the option variable.
-/// @param[in] value New value.
-/// @param errbuf Buffer for error messages.
-/// @param[in] errbuflen Length of `errbuf`.
-/// @param[in] opt_flags OPT_LOCAL, OPT_GLOBAL or OPT_MODELINE.
-///
-/// @return NULL on success, error message on error.
-static const char *set_num_option(int opt_idx, void *varp, long value, char *errbuf,
- size_t errbuflen, int opt_flags)
+/// Options that need some validation.
+static const char *validate_num_option(const long *pp, long *valuep)
{
- const char *errmsg = NULL;
- long old_value = *(long *)varp;
- long old_global_value = 0; // only used when setting a local and global option
- long old_Rows = Rows; // remember old Rows
- long *pp = (long *)varp;
-
- // Disallow changing some options from secure mode.
- if ((secure || sandbox != 0) && (options[opt_idx].flags & P_SECURE)) {
- return e_secure;
- }
-
- // Save the global value before changing anything. This is needed as for
- // a global-only option setting the "local value" in fact sets the global
- // value (since there is only one value).
- if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) {
- old_global_value = *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL);
- }
+ long value = *valuep;
// Many number options assume their value is in the signed int range.
if (value < INT_MIN || value > INT_MAX) {
return e_invarg;
}
- // Options that need some validation.
if (pp == &p_wh) {
if (value < 1) {
- errmsg = e_positive;
+ return e_positive;
} else if (p_wmh > value) {
- errmsg = e_winheight;
+ return e_winheight;
}
} else if (pp == &p_hh) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
}
} else if (pp == &p_wmh) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
} else if (value > p_wh) {
- errmsg = e_winheight;
+ return e_winheight;
}
} else if (pp == &p_wiw) {
if (value < 1) {
- errmsg = e_positive;
+ return e_positive;
} else if (p_wmw > value) {
- errmsg = e_winwidth;
+ return e_winwidth;
}
} else if (pp == &p_wmw) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
} else if (value > p_wiw) {
- errmsg = e_winwidth;
+ return e_winwidth;
}
} else if (pp == &p_mco) {
- value = MAX_MCO;
+ *valuep = MAX_MCO;
} else if (pp == &p_titlelen) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
}
} else if (pp == &p_uc) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
}
} else if (pp == &p_ch) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
} else {
p_ch_was_zero = value == 0;
}
} else if (pp == &p_tm) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
}
} else if (pp == &p_hi) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
} else if (value > 10000) {
- errmsg = e_invarg;
+ return e_invarg;
}
} else if (pp == &p_pyx) {
if (value == 0) {
- value = 3;
+ *valuep = 3;
} else if (value != 3) {
- errmsg = e_invarg;
+ return e_invarg;
}
} else if (pp == &p_re) {
if (value < 0 || value > 2) {
- errmsg = e_invarg;
+ return e_invarg;
}
} else if (pp == &p_report) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
}
} else if (pp == &p_so) {
if (value < 0 && full_screen) {
- errmsg = e_positive;
+ return e_positive;
}
} else if (pp == &p_siso) {
if (value < 0 && full_screen) {
- errmsg = e_positive;
+ return e_positive;
}
} else if (pp == &p_cwh) {
if (value < 1) {
- errmsg = e_positive;
+ return e_positive;
}
} else if (pp == &p_ut) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
}
} else if (pp == &p_ss) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
}
} else if (pp == &curwin->w_p_fdl || pp == &curwin->w_allbuf_opt.wo_fdl) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
}
} else if (pp == &curwin->w_p_cole || pp == &curwin->w_allbuf_opt.wo_cole) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
} else if (value > 3) {
- errmsg = e_invarg;
+ return e_invarg;
}
} else if (pp == &curwin->w_p_nuw || pp == &curwin->w_allbuf_opt.wo_nuw) {
if (value < 1) {
- errmsg = e_positive;
+ return e_positive;
} else if (value > MAX_NUMBERWIDTH) {
- errmsg = e_invarg;
+ return e_invarg;
}
} else if (pp == &curbuf->b_p_iminsert || pp == &p_iminsert) {
if (value < 0 || value > B_IMODE_LAST) {
- errmsg = e_invarg;
+ return e_invarg;
}
} else if (pp == &curbuf->b_p_imsearch || pp == &p_imsearch) {
if (value < -1 || value > B_IMODE_LAST) {
- errmsg = e_invarg;
+ return e_invarg;
}
} else if (pp == &curbuf->b_p_channel || pp == &p_channel) {
- errmsg = e_invarg;
+ return e_invarg;
} else if (pp == &curbuf->b_p_scbk || pp == &p_scbk) {
if (value < -1 || value > SB_MAX) {
- errmsg = e_invarg;
+ return e_invarg;
}
} else if (pp == &curbuf->b_p_sw || pp == &p_sw) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
}
} else if (pp == &curbuf->b_p_ts || pp == &p_ts) {
if (value < 1) {
- errmsg = e_positive;
+ return e_positive;
} else if (value > TABSTOP_MAX) {
- errmsg = e_invarg;
+ return e_invarg;
}
} else if (pp == &curbuf->b_p_tw || pp == &p_tw) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
}
} else if (pp == &p_wd) {
if (value < 0) {
- errmsg = e_positive;
+ return e_positive;
}
}
+ return NULL;
+}
+
+/// Set the value of a number option, taking care of side effects
+///
+/// @param[in] opt_idx Option index in options[] table.
+/// @param[out] varp Pointer to the option variable.
+/// @param[in] value New value.
+/// @param errbuf Buffer for error messages.
+/// @param[in] errbuflen Length of `errbuf`.
+/// @param[in] opt_flags OPT_LOCAL, OPT_GLOBAL or OPT_MODELINE.
+///
+/// @return NULL on success, error message on error.
+static const char *set_num_option(int opt_idx, void *varp, long value, char *errbuf,
+ size_t errbuflen, int opt_flags)
+{
+ long old_value = *(long *)varp;
+ long old_global_value = 0; // only used when setting a local and global option
+ long old_Rows = Rows; // remember old Rows
+ long *pp = (long *)varp;
+
+ // Disallow changing some options from secure mode.
+ if ((secure || sandbox != 0) && (options[opt_idx].flags & P_SECURE)) {
+ return e_secure;
+ }
+
+ // Save the global value before changing anything. This is needed as for
+ // a global-only option setting the "local value" in fact sets the global
+ // value (since there is only one value).
+ if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) {
+ old_global_value = *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL);
+ }
+
+ const char *errmsg = validate_num_option(pp, &value);
+
// Don't change the value and return early if validation failed.
if (errmsg != NULL) {
return errmsg;