aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-04-01 17:58:19 +0800
committerzeertzjq <zeertzjq@outlook.com>2022-11-05 19:35:56 +0800
commit3e60b9f1cc7a24e801d1ee38b4d03032cc6962f2 (patch)
tree78b8600d9b3683df0cb1f72af0656ef70139b659
parentda90be23088a3a0b8a517d66d446bdfef32e2872 (diff)
downloadrneovim-3e60b9f1cc7a24e801d1ee38b4d03032cc6962f2.tar.gz
rneovim-3e60b9f1cc7a24e801d1ee38b4d03032cc6962f2.tar.bz2
rneovim-3e60b9f1cc7a24e801d1ee38b4d03032cc6962f2.zip
vim-patch:8.2.4029: debugging NFA regexp my crash, cached indent may be wrong
Problem: Debugging NFA regexp my crash, cached indent may be wrong. Solution: Fix some debug warnings in the NFA regexp code. Make sure log_fd is set when used. Fix breakindent and indent caching. (Christian Brabandt, closes vim/vim#9482) https://github.com/vim/vim/commit/b2d85e3784ac89f5209489844c1ee0f54d117abb
-rw-r--r--src/nvim/indent.c47
-rw-r--r--src/nvim/optionstr.c10
-rw-r--r--src/nvim/regexp_nfa.c45
3 files changed, 65 insertions, 37 deletions
diff --git a/src/nvim/indent.c b/src/nvim/indent.c
index cb5819e946..c929a0d14a 100644
--- a/src/nvim/indent.c
+++ b/src/nvim/indent.c
@@ -783,19 +783,22 @@ int get_breakindent_win(win_T *wp, char_u *line)
FUNC_ATTR_NONNULL_ALL
{
static int prev_indent = 0; // Cached indent value.
- static long prev_ts = 0; // Cached tabstop value.
+ static long prev_ts = 0L; // Cached tabstop value.
static const char_u *prev_line = NULL; // cached pointer to line.
static varnumber_T prev_tick = 0; // Changedtick of cached value.
- static long *prev_vts = NULL; // Cached vartabs values.
+ static long *prev_vts = NULL; // Cached vartabs values.
+ static int prev_list = 0; // cached list value
+ static int prev_listopt = 0; // cached w_p_briopt_list value
int bri = 0;
// window width minus window margin space, i.e. what rests for text
const int eff_wwidth = wp->w_width_inner -
((wp->w_p_nu || wp->w_p_rnu)
&& (vim_strchr(p_cpo, CPO_NUMCOL) == NULL) ? number_width(wp) + 1 : 0);
- // used cached indent, unless pointer or 'tabstop' changed
+ // used cached indent, unless line, 'tabstop' or briopt_list changed
if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts
|| prev_tick != buf_get_changedtick(wp->w_buffer)
+ || prev_listopt != wp->w_briopt_list
|| prev_vts != wp->w_buffer->b_p_vts_array) {
prev_line = line;
prev_ts = wp->w_buffer->b_p_ts;
@@ -805,6 +808,25 @@ int get_breakindent_win(win_T *wp, char_u *line)
wp->w_buffer->b_p_ts,
wp->w_buffer->b_p_vts_array,
wp->w_p_list);
+ prev_listopt = wp->w_briopt_list;
+ // add additional indent for numbered lists
+ if (wp->w_briopt_list != 0) {
+ regmatch_T regmatch = {
+ .regprog = vim_regcomp(curbuf->b_p_flp,
+ RE_MAGIC + RE_STRING + RE_AUTO + RE_STRICT),
+ };
+ if (regmatch.regprog != NULL) {
+ regmatch.rm_ic = false;
+ if (vim_regexec(&regmatch, (char *)line, 0)) {
+ if (wp->w_briopt_list > 0) {
+ prev_list += wp->w_briopt_list;
+ } else {
+ prev_list = (int)(*regmatch.endp - *regmatch.startp);
+ }
+ }
+ vim_regfree(regmatch.regprog);
+ }
+ }
}
bri = prev_indent + wp->w_briopt_shift;
@@ -813,21 +835,10 @@ int get_breakindent_win(win_T *wp, char_u *line)
// add additional indent for numbered lists
if (wp->w_briopt_list != 0) {
- regmatch_T regmatch = {
- .regprog = vim_regcomp(curbuf->b_p_flp,
- RE_MAGIC + RE_STRING + RE_AUTO + RE_STRICT),
- };
-
- if (regmatch.regprog != NULL) {
- regmatch.rm_ic = false;
- if (vim_regexec(&regmatch, (char *)line, 0)) {
- if (wp->w_briopt_list > 0) {
- bri += wp->w_briopt_list;
- } else {
- bri = (int)(*regmatch.endp - *regmatch.startp);
- }
- }
- vim_regfree(regmatch.regprog);
+ if (wp->w_briopt_list > 0) {
+ bri += prev_list;
+ } else {
+ bri = prev_list;
}
}
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index 43628d2842..65bc9f60df 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -697,6 +697,10 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
if (briopt_check(curwin) == FAIL) {
errmsg = e_invarg;
}
+ // list setting requires a redraw
+ if (curwin->w_briopt_list) {
+ redraw_all_later(UPD_NOT_VALID);
+ }
} else if (varp == &p_isi
|| varp == &(curbuf->b_p_isk)
|| varp == &p_isp
@@ -1601,6 +1605,12 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
setmouse(); // in case 'mouse' changed
}
+ // Changing Formatlistpattern when briopt includes the list setting:
+ // redraw
+ if ((varp == &p_flp || varp == &(curbuf->b_p_flp)) && curwin->w_briopt_list) {
+ redraw_all_later(UPD_NOT_VALID);
+ }
+
if (curwin->w_curswant != MAXCOL
&& (opt->flags & (P_CURSWANT | P_RALL)) != 0) {
curwin->w_set_curswant = true;
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
index 2f4b1b98c1..d4d2ed28cc 100644
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.c
@@ -3370,8 +3370,8 @@ static void nfa_print_state2(FILE *debugf, nfa_state_T *state, garray_T *indent)
int last = indent->ga_len - 3;
char_u save[2];
- STRNCPY(save, &p[last], 2);
- STRNCPY(&p[last], "+-", 2);
+ STRNCPY(save, &p[last], 2); // NOLINT(runtime/printf)
+ memcpy(&p[last], "+-", 2);
fprintf(debugf, " %s", p);
STRNCPY(&p[last], save, 2); // NOLINT(runtime/printf)
} else {
@@ -4635,6 +4635,20 @@ static bool sub_equal(regsub_T *sub1, regsub_T *sub2)
}
#ifdef REGEXP_DEBUG
+static void open_debug_log(TriState result)
+{
+ log_fd = fopen(NFA_REGEXP_RUN_LOG, "a");
+ if (log_fd == NULL) {
+ emsg(_(e_log_open_failed));
+ log_fd = stderr;
+ }
+
+ fprintf(log_fd, "****************************\n");
+ fprintf(log_fd, "FINISHED RUNNING nfa_regmatch() recursively\n");
+ fprintf(log_fd, "MATCH = %s\n", result == kTrue ? "OK" : result == kNone ? "MAYBE" : "FALSE");
+ fprintf(log_fd, "****************************\n");
+}
+
static void report_state(char *action, regsub_T *sub, nfa_state_T *state, int lid, nfa_pim_T *pim)
{
int col;
@@ -4647,6 +4661,9 @@ static void report_state(char *action, regsub_T *sub, nfa_state_T *state, int li
col = (int)(sub->list.line[0].start - rex.line);
}
nfa_set_code(state->c);
+ if (log_fd == NULL) {
+ open_debug_log(kNone);
+ }
fprintf(log_fd, "> %s state %d to list %d. char %d: %s (start col %d)%s\n",
action, abs(state->id), lid, state->c, code, col,
pim_info(pim));
@@ -5668,16 +5685,7 @@ static int recursive_regmatch(nfa_state_T *state, nfa_pim_T *pim, nfa_regprog_T
nfa_endp = save_nfa_endp;
#ifdef REGEXP_DEBUG
- log_fd = fopen(NFA_REGEXP_RUN_LOG, "a");
- if (log_fd != NULL) {
- fprintf(log_fd, "****************************\n");
- fprintf(log_fd, "FINISHED RUNNING nfa_regmatch() recursively\n");
- fprintf(log_fd, "MATCH = %s\n", !result ? "false" : "OK");
- fprintf(log_fd, "****************************\n");
- } else {
- emsg(_(e_log_open_failed));
- log_fd = stderr;
- }
+ open_debug_log(result);
#endif
return result;
@@ -5983,16 +5991,15 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm
#ifdef REGEXP_DEBUG
log_fd = fopen(NFA_REGEXP_RUN_LOG, "a");
- if (log_fd != NULL) {
- fprintf(log_fd, "**********************************\n");
- nfa_set_code(start->c);
- fprintf(log_fd, " RUNNING nfa_regmatch() starting with state %d, code %s\n",
- abs(start->id), code);
- fprintf(log_fd, "**********************************\n");
- } else {
+ if (log_fd == NULL) {
emsg(_(e_log_open_failed));
log_fd = stderr;
}
+ fprintf(log_fd, "**********************************\n");
+ nfa_set_code(start->c);
+ fprintf(log_fd, " RUNNING nfa_regmatch() starting with state %d, code %s\n",
+ abs(start->id), code);
+ fprintf(log_fd, "**********************************\n");
#endif
thislist = &list[0];