Patch 8.0.0643
Problem: When 'hlsearch' is set and matching with the last search pattern
is very slow, Vim becomes unusable. Cannot quit search by
pressing CTRL-C.
Solution: When the search times out set a flag and don't try again. Check
for timeout and CTRL-C in NFA loop that adds states.
Files: src/screen.c, src/ex_cmds.c, src/quickfix.c, src/regexp.c,
src/proto/regexp.pro, src/regexp.h, src/search.c,
src/proto/search.pro, src/syntax.c, src/regexp_nfa.c, src/spell.c,
src/tag.c, src/gui.c, src/edit.c, src/evalfunc.c, src/ex_docmd.c,
src/ex_getln.c, src/normal.c
*** ../vim-8.0.0642/src/screen.c 2017-06-13 17:20:35.687782351 +0200
--- src/screen.c 2017-06-17 17:40:54.061966780 +0200
***************
*** 7800,7819 ****
int regprog_is_copy = (shl != &search_hl && cur != NULL
&& shl == &cur->hl
&& cur->match.regprog == cur->hl.rm.regprog);
nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum,
matchcol,
#ifdef FEAT_RELTIME
! &(shl->tm)
#else
! NULL
#endif
);
/* Copy the regprog, in case it got freed and recompiled. */
if (regprog_is_copy)
cur->match.regprog = cur->hl.rm.regprog;
! if (called_emsg || got_int)
{
/* Error while handling regexp: stop using this regexp. */
if (shl == &search_hl)
--- 7800,7820 ----
int regprog_is_copy = (shl != &search_hl && cur != NULL
&& shl == &cur->hl
&& cur->match.regprog == cur->hl.rm.regprog);
+ int timed_out = FALSE;
nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum,
matchcol,
#ifdef FEAT_RELTIME
! &(shl->tm), &timed_out
#else
! NULL, NULL
#endif
);
/* Copy the regprog, in case it got freed and recompiled. */
if (regprog_is_copy)
cur->match.regprog = cur->hl.rm.regprog;
! if (called_emsg || got_int || timed_out)
{
/* Error while handling regexp: stop using this regexp. */
if (shl == &search_hl)
*** ../vim-8.0.0642/src/ex_cmds.c 2017-06-10 14:29:26.766871128 +0200
--- src/ex_cmds.c 2017-06-17 17:41:44.501599148 +0200
***************
*** 5096,5102 ****
); ++lnum)
{
nmatch = vim_regexec_multi(®match, curwin, curbuf, lnum,
! (colnr_T)0, NULL);
if (nmatch)
{
colnr_T copycol;
--- 5096,5102 ----
); ++lnum)
{
nmatch = vim_regexec_multi(®match, curwin, curbuf, lnum,
! (colnr_T)0, NULL, NULL);
if (nmatch)
{
colnr_T copycol;
***************
*** 5695,5701 ****
|| nmatch_tl > 0
|| (nmatch = vim_regexec_multi(®match, curwin,
curbuf, sub_firstlnum,
! matchcol, NULL)) == 0
|| regmatch.startpos[0].lnum > 0)
{
if (new_start != NULL)
--- 5695,5701 ----
|| nmatch_tl > 0
|| (nmatch = vim_regexec_multi(®match, curwin,
curbuf, sub_firstlnum,
! matchcol, NULL, NULL)) == 0
|| regmatch.startpos[0].lnum > 0)
{
if (new_start != NULL)
***************
*** 5760,5766 ****
}
if (nmatch == -1 && !lastone)
nmatch = vim_regexec_multi(®match, curwin, curbuf,
! sub_firstlnum, matchcol, NULL);
/*
* 5. break if there isn't another match in this line
--- 5760,5766 ----
}
if (nmatch == -1 && !lastone)
nmatch = vim_regexec_multi(®match, curwin, curbuf,
! sub_firstlnum, matchcol, NULL, NULL);
/*
* 5. break if there isn't another match in this line
***************
*** 6012,6018 ****
{
lnum = curwin->w_cursor.lnum;
match = vim_regexec_multi(®match, curwin, curbuf, lnum,
! (colnr_T)0, NULL);
if ((type == 'g' && match) || (type == 'v' && !match))
global_exe_one(cmd, lnum);
}
--- 6012,6018 ----
{
lnum = curwin->w_cursor.lnum;
match = vim_regexec_multi(®match, curwin, curbuf, lnum,
! (colnr_T)0, NULL, NULL);
if ((type == 'g' && match) || (type == 'v' && !match))
global_exe_one(cmd, lnum);
}
***************
*** 6025,6031 ****
{
/* a match on this line? */
match = vim_regexec_multi(®match, curwin, curbuf, lnum,
! (colnr_T)0, NULL);
if ((type == 'g' && match) || (type == 'v' && !match))
{
ml_setmarked(lnum);
--- 6025,6031 ----
{
/* a match on this line? */
match = vim_regexec_multi(®match, curwin, curbuf, lnum,
! (colnr_T)0, NULL, NULL);
if ((type == 'g' && match) || (type == 'v' && !match))
{
ml_setmarked(lnum);
*** ../vim-8.0.0642/src/quickfix.c 2017-06-13 17:20:35.683782375 +0200
--- src/quickfix.c 2017-06-17 18:17:49.657686222 +0200
***************
*** 2415,2421 ****
save_cursor = curwin->w_cursor;
curwin->w_cursor.lnum = 0;
if (!do_search(NULL, '/', qf_ptr->qf_pattern, (long)1,
! SEARCH_KEEP, NULL))
curwin->w_cursor = save_cursor;
}
--- 2415,2421 ----
save_cursor = curwin->w_cursor;
curwin->w_cursor.lnum = 0;
if (!do_search(NULL, '/', qf_ptr->qf_pattern, (long)1,
! SEARCH_KEEP, NULL, NULL))
curwin->w_cursor = save_cursor;
}
***************
*** 4237,4243 ****
{
col = 0;
while (vim_regexec_multi(®match, curwin, buf, lnum,
! col, NULL) > 0)
{
/* Pass the buffer number so that it gets used even for a
* dummy buffer, unless duplicate_name is set, then the
--- 4237,4243 ----
{
col = 0;
while (vim_regexec_multi(®match, curwin, buf, lnum,
! col, NULL, NULL) > 0)
{
/* Pass the buffer number so that it gets used even for a
* dummy buffer, unless duplicate_name is set, then the
*** ../vim-8.0.0642/src/regexp.c 2017-06-05 17:53:33.475700562 +0200
--- src/regexp.c 2017-06-17 18:05:45.706987502 +0200
***************
*** 3479,3485 ****
} regbehind_T;
static char_u *reg_getline(linenr_T lnum);
! static long bt_regexec_both(char_u *line, colnr_T col, proftime_T *tm);
static long regtry(bt_regprog_T *prog, colnr_T col);
static void cleanup_subexpr(void);
#ifdef FEAT_SYN_HL
--- 3479,3485 ----
} regbehind_T;
static char_u *reg_getline(linenr_T lnum);
! static long bt_regexec_both(char_u *line, colnr_T col, proftime_T *tm, int
*timed_out);
static long regtry(bt_regprog_T *prog, colnr_T col);
static void cleanup_subexpr(void);
#ifdef FEAT_SYN_HL
***************
*** 3722,3728 ****
#endif
rex.reg_maxcol = 0;
! return bt_regexec_both(line, col, NULL);
}
/*
--- 3722,3728 ----
#endif
rex.reg_maxcol = 0;
! return bt_regexec_both(line, col, NULL, NULL);
}
/*
***************
*** 3740,3746 ****
buf_T *buf, /* buffer in which to search */
linenr_T lnum, /* nr of line to start looking for match */
colnr_T col, /* column to start looking for match */
! proftime_T *tm) /* timeout limit or NULL */
{
rex.reg_match = NULL;
rex.reg_mmatch = rmp;
--- 3740,3747 ----
buf_T *buf, /* buffer in which to search */
linenr_T lnum, /* nr of line to start looking for match */
colnr_T col, /* column to start looking for match */
! proftime_T *tm, /* timeout limit or NULL */
! int *timed_out) /* flag set on timeout or NULL */
{
rex.reg_match = NULL;
rex.reg_mmatch = rmp;
***************
*** 3755,3761 ****
#endif
rex.reg_maxcol = rmp->rmm_maxcol;
! return bt_regexec_both(NULL, col, tm);
}
/*
--- 3756,3762 ----
#endif
rex.reg_maxcol = rmp->rmm_maxcol;
! return bt_regexec_both(NULL, col, tm, timed_out);
}
/*
***************
*** 3767,3773 ****
bt_regexec_both(
char_u *line,
colnr_T col, /* column to start looking for match */
! proftime_T *tm UNUSED) /* timeout limit or NULL */
{
bt_regprog_T *prog;
char_u *s;
--- 3768,3775 ----
bt_regexec_both(
char_u *line,
colnr_T col, /* column to start looking for match */
! proftime_T *tm UNUSED, /* timeout limit or NULL */
! int *timed_out UNUSED) /* flag set on timeout or NULL
*/
{
bt_regprog_T *prog;
char_u *s;
***************
*** 3968,3974 ****
--- 3970,3980 ----
{
tm_count = 0;
if (profile_passed_limit(tm))
+ {
+ if (timed_out != NULL)
+ *timed_out = TRUE;
break;
+ }
}
#endif
}
***************
*** 8308,8314 ****
buf_T *buf, /* buffer in which to search */
linenr_T lnum, /* nr of line to start looking for match */
colnr_T col, /* column to start looking for match */
! proftime_T *tm) /* timeout limit or NULL */
{
int result;
regexec_T rex_save;
--- 8314,8321 ----
buf_T *buf, /* buffer in which to search */
linenr_T lnum, /* nr of line to start looking for match */
colnr_T col, /* column to start looking for match */
! proftime_T *tm, /* timeout limit or NULL */
! int *timed_out) /* flag is set when timeout limit
reached */
{
int result;
regexec_T rex_save;
***************
*** 8319,8325 ****
rex_save = rex;
rex_in_use = TRUE;
! result = rmp->regprog->engine->regexec_multi(rmp, win, buf, lnum, col,
tm);
/* NFA engine aborted because it's very slow. */
if (rmp->regprog->re_engine == AUTOMATIC_ENGINE
--- 8326,8333 ----
rex_save = rex;
rex_in_use = TRUE;
! result = rmp->regprog->engine->regexec_multi(
! rmp, win, buf, lnum, col, tm, timed_out);
/* NFA engine aborted because it's very slow. */
if (rmp->regprog->re_engine == AUTOMATIC_ENGINE
***************
*** 8339,8345 ****
rmp->regprog = vim_regcomp(pat, re_flags);
if (rmp->regprog != NULL)
result = rmp->regprog->engine->regexec_multi(
! rmp, win, buf, lnum, col, tm);
vim_free(pat);
}
p_re = save_p_re;
--- 8347,8353 ----
rmp->regprog = vim_regcomp(pat, re_flags);
if (rmp->regprog != NULL)
result = rmp->regprog->engine->regexec_multi(
! rmp, win, buf, lnum, col, tm, timed_out);
vim_free(pat);
}
p_re = save_p_re;
*** ../vim-8.0.0642/src/proto/regexp.pro 2016-09-12 13:04:17.000000000
+0200
--- src/proto/regexp.pro 2017-06-17 17:51:04.105477928 +0200
***************
*** 16,20 ****
int vim_regexec_prog(regprog_T **prog, int ignore_case, char_u *line, colnr_T
col);
int vim_regexec(regmatch_T *rmp, char_u *line, colnr_T col);
int vim_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col);
! long vim_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T
lnum, colnr_T col, proftime_T *tm);
/* vim: set ft=c : */
--- 16,20 ----
int vim_regexec_prog(regprog_T **prog, int ignore_case, char_u *line, colnr_T
col);
int vim_regexec(regmatch_T *rmp, char_u *line, colnr_T col);
int vim_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col);
! long vim_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T
lnum, colnr_T col, proftime_T *tm, int *timed_out);
/* vim: set ft=c : */
*** ../vim-8.0.0642/src/regexp.h 2016-08-29 22:42:20.000000000 +0200
--- src/regexp.h 2017-06-17 17:52:18.816926472 +0200
***************
*** 165,172 ****
{
regprog_T *(*regcomp)(char_u*, int);
void (*regfree)(regprog_T *);
! int (*regexec_nl)(regmatch_T*, char_u*, colnr_T, int);
! long (*regexec_multi)(regmmatch_T*, win_T*, buf_T*, linenr_T,
colnr_T, proftime_T*);
char_u *expr;
};
--- 165,172 ----
{
regprog_T *(*regcomp)(char_u*, int);
void (*regfree)(regprog_T *);
! int (*regexec_nl)(regmatch_T *, char_u *, colnr_T, int);
! long (*regexec_multi)(regmmatch_T *, win_T *, buf_T *, linenr_T,
colnr_T, proftime_T *, int *);
char_u *expr;
};
*** ../vim-8.0.0642/src/search.c 2017-06-05 19:56:01.124964522 +0200
--- src/search.c 2017-06-17 18:08:22.637835726 +0200
***************
*** 593,599 ****
int options,
int pat_use, /* which pattern to use when "pat" is
empty */
linenr_T stop_lnum, /* stop after this line number when != 0 */
! proftime_T *tm UNUSED) /* timeout limit or NULL */
{
int found;
linenr_T lnum; /* no init to shut up Apollo cc */
--- 593,600 ----
int options,
int pat_use, /* which pattern to use when "pat" is
empty */
linenr_T stop_lnum, /* stop after this line number when != 0 */
! proftime_T *tm UNUSED, /* timeout limit or NULL */
! int *timed_out UNUSED) /* set when timed out or NULL */
{
int found;
linenr_T lnum; /* no init to shut up Apollo cc */
***************
*** 715,727 ****
nmatched = vim_regexec_multi(®match, win, buf,
lnum, col,
#ifdef FEAT_RELTIME
! tm
#else
! NULL
#endif
);
/* Abort searching on an error (e.g., out of stack). */
! if (called_emsg)
break;
if (nmatched > 0)
{
--- 716,732 ----
nmatched = vim_regexec_multi(®match, win, buf,
lnum, col,
#ifdef FEAT_RELTIME
! tm, timed_out
#else
! NULL, NULL
#endif
);
/* Abort searching on an error (e.g., out of stack). */
! if (called_emsg
! #ifdef FEAT_RELTIME
! || (timed_out != NULL && *timed_out)
! #endif
! )
break;
if (nmatched > 0)
{
***************
*** 810,818 ****
win, buf, lnum + matchpos.lnum,
matchcol,
#ifdef FEAT_RELTIME
! tm
#else
! NULL
#endif
)) == 0)
{
--- 815,823 ----
win, buf, lnum + matchpos.lnum,
matchcol,
#ifdef FEAT_RELTIME
! tm, timed_out
#else
! NULL, NULL
#endif
)) == 0)
{
***************
*** 922,930 ****
win, buf, lnum + matchpos.lnum,
matchcol,
#ifdef FEAT_RELTIME
! tm
#else
! NULL
#endif
)) == 0)
break;
--- 927,935 ----
win, buf, lnum + matchpos.lnum,
matchcol,
#ifdef FEAT_RELTIME
! tm, timed_out
#else
! NULL, NULL
#endif
)) == 0)
break;
***************
*** 1019,1028 ****
* twice.
*/
if (!p_ws || stop_lnum != 0 || got_int || called_emsg
#ifdef FEAT_SEARCH_EXTRA
! || break_loop
#endif
! || found || loop)
break;
/*
--- 1024,1036 ----
* twice.
*/
if (!p_ws || stop_lnum != 0 || got_int || called_emsg
+ #ifdef FEAT_RELTIME
+ || (timed_out != NULL && *timed_out)
+ #endif
#ifdef FEAT_SEARCH_EXTRA
! || break_loop
#endif
! || found || loop)
break;
/*
***************
*** 1041,1046 ****
--- 1049,1057 ----
? top_bot_msg : bot_top_msg), TRUE);
}
if (got_int || called_emsg
+ #ifdef FEAT_RELTIME
+ || (timed_out != NULL && *timed_out)
+ #endif
#ifdef FEAT_SEARCH_EXTRA
|| break_loop
#endif
***************
*** 1147,1153 ****
char_u *pat,
long count,
int options,
! proftime_T *tm) /* timeout limit or NULL */
{
pos_T pos; /* position of the last match */
char_u *searchstr;
--- 1158,1165 ----
char_u *pat,
long count,
int options,
! proftime_T *tm, /* timeout limit or NULL */
! int *timed_out) /* flag set on timeout or NULL */
{
pos_T pos; /* position of the last match */
char_u *searchstr;
***************
*** 1433,1439 ****
(SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS
+ SEARCH_MSG + SEARCH_START
+ ((pat != NULL && *pat == ';') ? 0 : SEARCH_NOOF))),
! RE_LAST, (linenr_T)0, tm);
if (dircp != NULL)
*dircp = dirc; /* restore second '/' or '?' for normal_cmd() */
--- 1445,1451 ----
(SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS
+ SEARCH_MSG + SEARCH_START
+ ((pat != NULL && *pat == ';') ? 0 : SEARCH_NOOF))),
! RE_LAST, (linenr_T)0, tm, timed_out);
if (dircp != NULL)
*dircp = dirc; /* restore second '/' or '?' for normal_cmd() */
***************
*** 4672,4678 ****
result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD),
spats[last_idx].pat, (long) (i ? count : 1),
! SEARCH_KEEP | flags, RE_SEARCH, 0, NULL);
/* First search may fail, but then start searching from the
* beginning of the file (cursor might be on the search match)
--- 4684,4690 ----
result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD),
spats[last_idx].pat, (long) (i ? count : 1),
! SEARCH_KEEP | flags, RE_SEARCH, 0, NULL, NULL);
/* First search may fail, but then start searching from the
* beginning of the file (cursor might be on the search match)
***************
*** 4719,4725 ****
* already on the next match */
if (!one_char)
result = searchit(curwin, curbuf, &pos, (forward ? FORWARD : BACKWARD),
! spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0, NULL);
if (!VIsual_active)
VIsual = start_pos;
--- 4731,4738 ----
* already on the next match */
if (!one_char)
result = searchit(curwin, curbuf, &pos, (forward ? FORWARD : BACKWARD),
! spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0,
! NULL, NULL);
if (!VIsual_active)
VIsual = start_pos;
***************
*** 4800,4806 ****
}
if (searchit(curwin, curbuf, &pos, FORWARD, pattern, 1,
! SEARCH_KEEP + flag, RE_SEARCH, 0, NULL) != FAIL)
{
/* Zero-width pattern should match somewhere, then we can check if
* start and end are in the same position. */
--- 4813,4819 ----
}
if (searchit(curwin, curbuf, &pos, FORWARD, pattern, 1,
! SEARCH_KEEP + flag, RE_SEARCH, 0, NULL, NULL) != FAIL)
{
/* Zero-width pattern should match somewhere, then we can check if
* start and end are in the same position. */
***************
*** 4809,4815 ****
{
regmatch.startpos[0].col++;
nmatched = vim_regexec_multi(®match, curwin, curbuf,
! pos.lnum, regmatch.startpos[0].col,
NULL);
if (!nmatched)
break;
} while (regmatch.startpos[0].col < pos.col);
--- 4822,4828 ----
{
regmatch.startpos[0].col++;
nmatched = vim_regexec_multi(®match, curwin, curbuf,
! pos.lnum, regmatch.startpos[0].col, NULL, NULL);
if (!nmatched)
break;
} while (regmatch.startpos[0].col < pos.col);
*** ../vim-8.0.0642/src/proto/search.pro 2016-09-12 13:04:18.000000000
+0200
--- src/proto/search.pro 2017-06-17 18:07:47.278095159 +0200
***************
*** 19,27 ****
void reset_search_dir(void);
void set_last_search_pat(char_u *s, int idx, int magic, int setlast);
void last_pat_prog(regmmatch_T *regmatch);
! int searchit(win_T *win, buf_T *buf, pos_T *pos, int dir, char_u *pat, long
count, int options, int pat_use, linenr_T stop_lnum, proftime_T *tm);
void set_search_direction(int cdir);
! int do_search(oparg_T *oap, int dirc, char_u *pat, long count, int options,
proftime_T *tm);
int search_for_exact_line(buf_T *buf, pos_T *pos, int dir, char_u *pat);
int searchc(cmdarg_T *cap, int t_cmd);
pos_T *findmatch(oparg_T *oap, int initc);
--- 19,27 ----
void reset_search_dir(void);
void set_last_search_pat(char_u *s, int idx, int magic, int setlast);
void last_pat_prog(regmmatch_T *regmatch);
! int searchit(win_T *win, buf_T *buf, pos_T *pos, int dir, char_u *pat, long
count, int options, int pat_use, linenr_T stop_lnum, proftime_T *tm, int
*timed_out);
void set_search_direction(int cdir);
! int do_search(oparg_T *oap, int dirc, char_u *pat, long count, int options,
proftime_T *tm, int *timed_out);
int search_for_exact_line(buf_T *buf, pos_T *pos, int dir, char_u *pat);
int searchc(cmdarg_T *cap, int t_cmd);
pos_T *findmatch(oparg_T *oap, int initc);
*** ../vim-8.0.0642/src/syntax.c 2017-06-13 17:20:35.687782351 +0200
--- src/syntax.c 2017-06-17 17:48:45.270503447 +0200
***************
*** 3303,3309 ****
#endif
rmp->rmm_maxcol = syn_buf->b_p_smc;
! r = vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col, NULL);
#ifdef FEAT_PROFILE
if (syn_time_on)
--- 3303,3309 ----
#endif
rmp->rmm_maxcol = syn_buf->b_p_smc;
! r = vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col, NULL, NULL);
#ifdef FEAT_PROFILE
if (syn_time_on)
*** ../vim-8.0.0642/src/regexp_nfa.c 2017-06-05 16:54:04.424407859 +0200
--- src/regexp_nfa.c 2017-06-17 18:30:30.804088832 +0200
***************
*** 311,322 ****
static void nfa_save_listids(nfa_regprog_T *prog, int *list);
static void nfa_restore_listids(nfa_regprog_T *prog, int *list);
static int nfa_re_num_cmp(long_u val, int op, long_u pos);
! static long nfa_regtry(nfa_regprog_T *prog, colnr_T col, proftime_T *tm);
! static long nfa_regexec_both(char_u *line, colnr_T col, proftime_T *tm);
static regprog_T *nfa_regcomp(char_u *expr, int re_flags);
static void nfa_regfree(regprog_T *prog);
static int nfa_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col, int
line_lbr);
! static long nfa_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf,
linenr_T lnum, colnr_T col, proftime_T *tm);
static int match_follows(nfa_state_T *startstate, int depth);
static int failure_chance(nfa_state_T *state, int depth);
--- 311,322 ----
static void nfa_save_listids(nfa_regprog_T *prog, int *list);
static void nfa_restore_listids(nfa_regprog_T *prog, int *list);
static int nfa_re_num_cmp(long_u val, int op, long_u pos);
! static long nfa_regtry(nfa_regprog_T *prog, colnr_T col, proftime_T *tm, int
*timed_out);
! static long nfa_regexec_both(char_u *line, colnr_T col, proftime_T *tm, int
*timed_out);
static regprog_T *nfa_regcomp(char_u *expr, int re_flags);
static void nfa_regfree(regprog_T *prog);
static int nfa_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col, int
line_lbr);
! static long nfa_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf,
linenr_T lnum, colnr_T col, proftime_T *tm, int *timed_out);
static int match_follows(nfa_state_T *startstate, int depth);
static int failure_chance(nfa_state_T *state, int depth);
***************
*** 3959,3964 ****
--- 3959,3965 ----
static int nfa_match;
#ifdef FEAT_RELTIME
static proftime_T *nfa_time_limit;
+ static int *nfa_timed_out;
static int nfa_time_count;
#endif
***************
*** 5508,5513 ****
--- 5509,5528 ----
return 0L;
}
+ #ifdef FEAT_RELTIME
+ static int
+ nfa_did_time_out()
+ {
+ if (nfa_time_limit != NULL && profile_passed_limit(nfa_time_limit))
+ {
+ if (nfa_timed_out != NULL)
+ *nfa_timed_out = TRUE;
+ return TRUE;
+ }
+ return FALSE;
+ }
+ #endif
+
/*
* Main matching routine.
*
***************
*** 5551,5557 ****
if (got_int)
return FALSE;
#ifdef FEAT_RELTIME
! if (nfa_time_limit != NULL && profile_passed_limit(nfa_time_limit))
return FALSE;
#endif
--- 5566,5572 ----
if (got_int)
return FALSE;
#ifdef FEAT_RELTIME
! if (nfa_did_time_out())
return FALSE;
#endif
***************
*** 5694,5699 ****
--- 5709,5727 ----
/* compute nextlist */
for (listidx = 0; listidx < thislist->n; ++listidx)
{
+ /* If the list gets very long there probably is something wrong.
+ * At least allow interrupting with CTRL-C. */
+ fast_breakcheck();
+ if (got_int)
+ break;
+ #ifdef FEAT_RELTIME
+ if (nfa_time_limit != NULL && ++nfa_time_count == 20)
+ {
+ nfa_time_count = 0;
+ if (nfa_did_time_out())
+ break;
+ }
+ #endif
t = &thislist->t[listidx];
#ifdef NFA_REGEXP_DEBUG_LOG
***************
*** 6915,6921 ****
if (nfa_time_limit != NULL && ++nfa_time_count == 20)
{
nfa_time_count = 0;
! if (profile_passed_limit(nfa_time_limit))
break;
}
#endif
--- 6943,6949 ----
if (nfa_time_limit != NULL && ++nfa_time_count == 20)
{
nfa_time_count = 0;
! if (nfa_did_time_out())
break;
}
#endif
***************
*** 6948,6954 ****
nfa_regtry(
nfa_regprog_T *prog,
colnr_T col,
! proftime_T *tm UNUSED) /* timeout limit or NULL */
{
int i;
regsubs_T subs, m;
--- 6976,6983 ----
nfa_regtry(
nfa_regprog_T *prog,
colnr_T col,
! proftime_T *tm UNUSED, /* timeout limit or NULL */
! int *timed_out UNUSED) /* flag set on timeout or NULL
*/
{
int i;
regsubs_T subs, m;
***************
*** 6961,6966 ****
--- 6990,6996 ----
reginput = regline + col;
#ifdef FEAT_RELTIME
nfa_time_limit = tm;
+ nfa_timed_out = timed_out;
nfa_time_count = 0;
#endif
***************
*** 7087,7093 ****
nfa_regexec_both(
char_u *line,
colnr_T startcol, /* column to start looking for match */
! proftime_T *tm) /* timeout limit or NULL */
{
nfa_regprog_T *prog;
long retval = 0L;
--- 7117,7124 ----
nfa_regexec_both(
char_u *line,
colnr_T startcol, /* column to start looking for match */
! proftime_T *tm, /* timeout limit or NULL */
! int *timed_out) /* flag set on timeout or NULL */
{
nfa_regprog_T *prog;
long retval = 0L;
***************
*** 7181,7187 ****
prog->state[i].lastlist[1] = 0;
}
! retval = nfa_regtry(prog, col, tm);
nfa_regengine.expr = NULL;
--- 7212,7218 ----
prog->state[i].lastlist[1] = 0;
}
! retval = nfa_regtry(prog, col, tm, timed_out);
nfa_regengine.expr = NULL;
***************
*** 7340,7346 ****
rex.reg_icombine = FALSE;
#endif
rex.reg_maxcol = 0;
! return nfa_regexec_both(line, col, NULL);
}
--- 7371,7377 ----
rex.reg_icombine = FALSE;
#endif
rex.reg_maxcol = 0;
! return nfa_regexec_both(line, col, NULL, NULL);
}
***************
*** 7376,7382 ****
buf_T *buf, /* buffer in which to search */
linenr_T lnum, /* nr of line to start looking for match */
colnr_T col, /* column to start looking for match */
! proftime_T *tm) /* timeout limit or NULL */
{
rex.reg_match = NULL;
rex.reg_mmatch = rmp;
--- 7407,7414 ----
buf_T *buf, /* buffer in which to search */
linenr_T lnum, /* nr of line to start looking for match */
colnr_T col, /* column to start looking for match */
! proftime_T *tm, /* timeout limit or NULL */
! int *timed_out) /* flag set on timeout or NULL */
{
rex.reg_match = NULL;
rex.reg_mmatch = rmp;
***************
*** 7391,7397 ****
#endif
rex.reg_maxcol = rmp->rmm_maxcol;
! return nfa_regexec_both(NULL, col, tm);
}
#ifdef DEBUG
--- 7423,7429 ----
#endif
rex.reg_maxcol = rmp->rmm_maxcol;
! return nfa_regexec_both(NULL, col, tm, timed_out);
}
#ifdef DEBUG
*** ../vim-8.0.0642/src/spell.c 2017-04-22 23:49:48.442047574 +0200
--- src/spell.c 2017-06-17 18:08:42.177692383 +0200
***************
*** 3675,3681 ****
curwin->w_cursor.lnum = 0;
while (!got_int)
{
! if (do_search(NULL, '/', frompat, 1L, SEARCH_KEEP, NULL) == 0
|| u_save_cursor() == FAIL)
break;
--- 3675,3681 ----
curwin->w_cursor.lnum = 0;
while (!got_int)
{
! if (do_search(NULL, '/', frompat, 1L, SEARCH_KEEP, NULL, NULL) == 0
|| u_save_cursor() == FAIL)
break;
*** ../vim-8.0.0642/src/tag.c 2017-06-05 16:01:53.913848249 +0200
--- src/tag.c 2017-06-17 18:09:28.593351946 +0200
***************
*** 3308,3314 ****
save_lnum = curwin->w_cursor.lnum;
curwin->w_cursor.lnum = 0; /* start search before first line */
if (do_search(NULL, pbuf[0], pbuf + 1, (long)1,
! search_options, NULL))
retval = OK;
else
{
--- 3308,3314 ----
save_lnum = curwin->w_cursor.lnum;
curwin->w_cursor.lnum = 0; /* start search before first line */
if (do_search(NULL, pbuf[0], pbuf + 1, (long)1,
! search_options, NULL, NULL))
retval = OK;
else
{
***************
*** 3320,3326 ****
*/
p_ic = TRUE;
if (!do_search(NULL, pbuf[0], pbuf + 1, (long)1,
! search_options, NULL))
{
/*
* Failed to find pattern, take a guess: "^func ("
--- 3320,3326 ----
*/
p_ic = TRUE;
if (!do_search(NULL, pbuf[0], pbuf + 1, (long)1,
! search_options, NULL, NULL))
{
/*
* Failed to find pattern, take a guess: "^func ("
***************
*** 3331,3343 ****
*tagp.tagname_end = NUL;
sprintf((char *)pbuf, "^%s\\s\\*(", tagp.tagname);
if (!do_search(NULL, '/', pbuf, (long)1,
! search_options, NULL))
{
/* Guess again: "^char * \<func (" */
sprintf((char *)pbuf, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
tagp.tagname);
if (!do_search(NULL, '/', pbuf, (long)1,
! search_options, NULL))
found = 0;
}
*tagp.tagname_end = cc;
--- 3331,3343 ----
*tagp.tagname_end = NUL;
sprintf((char *)pbuf, "^%s\\s\\*(", tagp.tagname);
if (!do_search(NULL, '/', pbuf, (long)1,
! search_options, NULL, NULL))
{
/* Guess again: "^char * \<func (" */
sprintf((char *)pbuf, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
tagp.tagname);
if (!do_search(NULL, '/', pbuf, (long)1,
! search_options, NULL, NULL))
found = 0;
}
*tagp.tagname_end = cc;
*** ../vim-8.0.0642/src/gui.c 2017-06-05 13:31:52.503500012 +0200
--- src/gui.c 2017-06-17 18:09:41.253259106 +0200
***************
*** 5361,5367 ****
searchflags += SEARCH_START;
i = msg_scroll;
(void)do_search(NULL, down ? '/' : '?', ga.ga_data, 1L,
! searchflags, NULL);
msg_scroll = i; /* don't let an error message set msg_scroll */
}
--- 5361,5367 ----
searchflags += SEARCH_START;
i = msg_scroll;
(void)do_search(NULL, down ? '/' : '?', ga.ga_data, 1L,
! searchflags, NULL, NULL);
msg_scroll = i; /* don't let an error message set msg_scroll */
}
*** ../vim-8.0.0642/src/edit.c 2017-05-01 20:46:47.747526808 +0200
--- src/edit.c 2017-06-17 18:12:06.504194363 +0200
***************
*** 4512,4518 ****
found_new_match = searchit(NULL, ins_buf, pos,
compl_direction,
compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG,
! RE_LAST, (linenr_T)0, NULL);
--msg_silent;
if (!compl_started || set_match_pos)
{
--- 4512,4518 ----
found_new_match = searchit(NULL, ins_buf, pos,
compl_direction,
compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG,
! RE_LAST, (linenr_T)0, NULL, NULL);
--msg_silent;
if (!compl_started || set_match_pos)
{
*** ../vim-8.0.0642/src/evalfunc.c 2017-06-13 19:38:33.301791799 +0200
--- src/evalfunc.c 2017-06-17 18:14:04.295331490 +0200
***************
*** 9281,9287 ****
pos = save_cursor = curwin->w_cursor;
subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L,
! options, RE_SEARCH, (linenr_T)lnum_stop, &tm);
if (subpatnum != FAIL)
{
if (flags & SP_SUBPAT)
--- 9281,9287 ----
pos = save_cursor = curwin->w_cursor;
subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L,
! options, RE_SEARCH, (linenr_T)lnum_stop, &tm, NULL);
if (subpatnum != FAIL)
{
if (flags & SP_SUBPAT)
***************
*** 9619,9625 ****
for (;;)
{
n = searchit(curwin, curbuf, &pos, dir, pat, 1L,
! options, RE_SEARCH, lnum_stop, &tm);
if (n == FAIL || (firstpos.lnum != 0 && EQUAL_POS(pos, firstpos)))
/* didn't find it or found the first match again: FAIL */
break;
--- 9619,9625 ----
for (;;)
{
n = searchit(curwin, curbuf, &pos, dir, pat, 1L,
! options, RE_SEARCH, lnum_stop, &tm, NULL);
if (n == FAIL || (firstpos.lnum != 0 && EQUAL_POS(pos, firstpos)))
/* didn't find it or found the first match again: FAIL */
break;
*** ../vim-8.0.0642/src/ex_docmd.c 2017-06-04 20:43:43.956009665 +0200
--- src/ex_docmd.c 2017-06-17 18:14:53.714969622 +0200
***************
*** 4556,4562 ****
curwin->w_cursor.col = 0;
searchcmdlen = 0;
if (!do_search(NULL, c, cmd, 1L,
! SEARCH_HIS | SEARCH_MSG, NULL))
{
curwin->w_cursor = pos;
cmd = NULL;
--- 4556,4562 ----
curwin->w_cursor.col = 0;
searchcmdlen = 0;
if (!do_search(NULL, c, cmd, 1L,
! SEARCH_HIS | SEARCH_MSG, NULL, NULL))
{
curwin->w_cursor = pos;
cmd = NULL;
***************
*** 4613,4619 ****
if (searchit(curwin, curbuf, &pos,
*cmd == '?' ? BACKWARD : FORWARD,
(char_u *)"", 1L, SEARCH_MSG,
! i, (linenr_T)0, NULL) != FAIL)
lnum = pos.lnum;
else
{
--- 4613,4619 ----
if (searchit(curwin, curbuf, &pos,
*cmd == '?' ? BACKWARD : FORWARD,
(char_u *)"", 1L, SEARCH_MSG,
! i, (linenr_T)0, NULL, NULL) != FAIL)
lnum = pos.lnum;
else
{
*** ../vim-8.0.0642/src/ex_getln.c 2017-04-30 19:39:32.650857838 +0200
--- src/ex_getln.c 2017-06-17 18:16:07.674428637 +0200
***************
*** 1693,1699 ****
i = searchit(curwin, curbuf, &t,
c == Ctrl_G ? FORWARD : BACKWARD,
ccline.cmdbuff, count, search_flags,
! RE_SEARCH, 0, NULL);
--emsg_off;
if (i)
{
--- 1693,1699 ----
i = searchit(curwin, curbuf, &t,
c == Ctrl_G ? FORWARD : BACKWARD,
ccline.cmdbuff, count, search_flags,
! RE_SEARCH, 0, NULL, NULL);
--emsg_off;
if (i)
{
***************
*** 1903,1911 ****
i = do_search(NULL, firstc, ccline.cmdbuff, count,
SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK,
#ifdef FEAT_RELTIME
! &tm
#else
! NULL
#endif
);
--emsg_off;
--- 1903,1911 ----
i = do_search(NULL, firstc, ccline.cmdbuff, count,
SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK,
#ifdef FEAT_RELTIME
! &tm, NULL
#else
! NULL, NULL
#endif
);
--emsg_off;
*** ../vim-8.0.0642/src/normal.c 2017-06-04 15:33:44.541488336 +0200
--- src/normal.c 2017-06-17 18:17:31.701816911 +0200
***************
*** 4358,4364 ****
{
valid = FALSE;
t = searchit(curwin, curbuf, &curwin->w_cursor, FORWARD,
! pat, 1L, searchflags, RE_LAST, (linenr_T)0, NULL);
if (curwin->w_cursor.lnum >= old_pos.lnum)
t = FAIL; /* match after start is failure too */
--- 4358,4364 ----
{
valid = FALSE;
t = searchit(curwin, curbuf, &curwin->w_cursor, FORWARD,
! pat, 1L, searchflags, RE_LAST, (linenr_T)0, NULL, NULL);
if (curwin->w_cursor.lnum >= old_pos.lnum)
t = FAIL; /* match after start is failure too */
***************
*** 6380,6386 ****
curwin->w_set_curswant = TRUE;
i = do_search(cap->oap, dir, pat, cap->count1,
! opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, NULL);
if (i == 0)
clearop(cap->oap);
else
--- 6380,6386 ----
curwin->w_set_curswant = TRUE;
i = do_search(cap->oap, dir, pat, cap->count1,
! opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, NULL, NULL);
if (i == 0)
clearop(cap->oap);
else
*** ../vim-8.0.0642/src/version.c 2017-06-13 19:38:33.301791799 +0200
--- src/version.c 2017-06-17 18:26:02.866059733 +0200
***************
*** 766,767 ****
--- 766,769 ----
{ /* Add new patch number below this line */
+ /**/
+ 643,
/**/
--
A fine is a tax for doing wrong. A tax is a fine for doing well.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.