aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/buffer.c47
-rw-r--r--src/nvim/ex_cmds2.c5
-rw-r--r--src/nvim/fileio.c54
-rw-r--r--src/nvim/quickfix.c4
-rw-r--r--src/nvim/regexp.c14
-rw-r--r--src/nvim/spell.c27
-rw-r--r--src/nvim/syntax.c28
-rw-r--r--src/nvim/version.c4
8 files changed, 94 insertions, 89 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 1465b13c00..395b20b219 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -77,8 +77,6 @@
#include "nvim/os/time.h"
#include "nvim/os/input.h"
-#define HAVE_BUFLIST_MATCH
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "buffer.c.generated.h"
#endif
@@ -1721,7 +1719,6 @@ buflist_findpat (
int curtab_only /* find buffers in current tab only */
)
{
- regprog_T *prog;
int match = -1;
int find_listed;
char_u *pat;
@@ -1765,8 +1762,10 @@ buflist_findpat (
p = pat;
if (*p == '^' && !(attempt & 1)) /* add/remove '^' */
++p;
- prog = vim_regcomp(p, p_magic ? RE_MAGIC : 0);
- if (prog == NULL) {
+
+ regmatch_T regmatch;
+ regmatch.regprog = vim_regcomp(p, p_magic ? RE_MAGIC : 0);
+ if (regmatch.regprog == NULL) {
xfree(pat);
return -1;
}
@@ -1774,7 +1773,7 @@ buflist_findpat (
FOR_ALL_BUFFERS(buf) {
if (buf->b_p_bl == find_listed
&& (!diffmode || diff_mode_buf(buf))
- && buflist_match(prog, buf, false) != NULL) {
+ && buflist_match(&regmatch, buf, false) != NULL) {
if (curtab_only) {
/* Ignore the match if the buffer is not open in
* the current tab. */
@@ -1797,7 +1796,7 @@ buflist_findpat (
}
}
- vim_regfree(prog);
+ vim_regfree(regmatch.regprog);
if (match >= 0) /* found one match */
break;
}
@@ -1831,7 +1830,6 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options)
int round;
char_u *p;
int attempt;
- regprog_T *prog;
char_u *patc;
*num_file = 0; /* return values in case of FAIL */
@@ -1852,8 +1850,10 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options)
for (attempt = 0; attempt <= 1; ++attempt) {
if (attempt > 0 && patc == pat)
break; /* there was no anchor, no need to try again */
- prog = vim_regcomp(patc + attempt * 11, RE_MAGIC);
- if (prog == NULL) {
+
+ regmatch_T regmatch;
+ regmatch.regprog = vim_regcomp(patc + attempt * 11, RE_MAGIC);
+ if (regmatch.regprog == NULL) {
if (patc != pat)
xfree(patc);
return FAIL;
@@ -1868,7 +1868,7 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options)
FOR_ALL_BUFFERS(buf) {
if (!buf->b_p_bl) /* skip unlisted buffers */
continue;
- p = buflist_match(prog, buf, p_wic);
+ p = buflist_match(&regmatch, buf, p_wic);
if (p != NULL) {
if (round == 1)
++count;
@@ -1887,7 +1887,7 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options)
*file = xmalloc(count * sizeof(**file));
}
}
- vim_regfree(prog);
+ vim_regfree(regmatch.regprog);
if (count) /* match(es) found, break here */
break;
}
@@ -1900,20 +1900,16 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options)
}
-#ifdef HAVE_BUFLIST_MATCH
/// Check for a match on the file name for buffer "buf" with regprog "prog".
///
/// @param ignore_case When TRUE, ignore case. Use 'fic' otherwise.
-static char_u *buflist_match(regprog_T *prog, buf_T *buf, bool ignore_case)
+static char_u *buflist_match(regmatch_T *rmp, buf_T *buf, bool ignore_case)
{
- char_u *match;
-
- /* First try the short file name, then the long file name. */
- match = fname_match(prog, buf->b_sfname, ignore_case);
+ // First try the short file name, then the long file name.
+ char_u *match = fname_match(rmp, buf->b_sfname, ignore_case);
if (match == NULL) {
- match = fname_match(prog, buf->b_ffname, ignore_case);
+ match = fname_match(rmp, buf->b_ffname, ignore_case);
}
-
return match;
}
@@ -1921,22 +1917,20 @@ static char_u *buflist_match(regprog_T *prog, buf_T *buf, bool ignore_case)
///
/// @param ignore_case When TRUE, ignore case. Use 'fileignorecase' otherwise.
/// @return "name" when there is a match, NULL when not.
-static char_u *fname_match(regprog_T *prog, char_u *name, bool ignore_case)
+static char_u *fname_match(regmatch_T *rmp, char_u *name, bool ignore_case)
{
char_u *match = NULL;
char_u *p;
- regmatch_T regmatch;
if (name != NULL) {
- regmatch.regprog = prog;
// Ignore case when 'fileignorecase' or the argument is set.
- regmatch.rm_ic = p_fic || ignore_case;
- if (vim_regexec(&regmatch, name, (colnr_T)0))
+ rmp->rm_ic = p_fic || ignore_case;
+ if (vim_regexec(rmp, name, (colnr_T)0))
match = name;
else {
/* Replace $(HOME) with '~' and try matching again. */
p = home_replace_save(NULL, name);
- if (vim_regexec(&regmatch, p, (colnr_T)0))
+ if (vim_regexec(rmp, p, (colnr_T)0))
match = name;
xfree(p);
}
@@ -1944,7 +1938,6 @@ static char_u *fname_match(regprog_T *prog, char_u *name, bool ignore_case)
return match;
}
-#endif
/*
* find file in buffer list by number
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index a2577513d4..98e6d87196 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -687,7 +687,6 @@ debuggy_find (
{
struct debuggy *bp;
linenr_T lnum = 0;
- regmatch_T regmatch;
char_u *name = fname;
int prev_got_int;
@@ -709,8 +708,6 @@ debuggy_find (
if (((bp->dbg_type == DBG_FILE) == file && (
gap == &prof_ga ||
(bp->dbg_lnum > after && (lnum == 0 || bp->dbg_lnum < lnum))))) {
- regmatch.regprog = bp->dbg_prog;
- regmatch.rm_ic = FALSE;
/*
* Save the value of got_int and reset it. We don't want a
* previous interruption cancel matching, only hitting CTRL-C
@@ -718,7 +715,7 @@ debuggy_find (
*/
prev_got_int = got_int;
got_int = FALSE;
- if (vim_regexec(&regmatch, name, (colnr_T)0)) {
+ if (vim_regexec_prog(&bp->dbg_prog, false, name, (colnr_T)0)) {
lnum = bp->dbg_lnum;
if (fp != NULL)
*fp = bp->dbg_forceit;
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index bb4b7a140b..0dcf43c659 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -6819,8 +6819,8 @@ auto_next_pat (
&& (apc->group == AUGROUP_ALL || apc->group == ap->group)) {
/* execution-condition */
if (ap->buflocal_nr == 0
- ? (match_file_pat(NULL, ap->reg_prog, apc->fname,
- apc->sfname, apc->tail, ap->allow_dirs))
+ ? match_file_pat(NULL, &ap->reg_prog, apc->fname, apc->sfname,
+ apc->tail, ap->allow_dirs)
: ap->buflocal_nr == apc->arg_bufnr) {
name = event_nr2name(apc->event);
s = _("%s Auto commands for \"%s\"");
@@ -6934,8 +6934,8 @@ int has_autocmd(event_T event, char_u *sfname, buf_T *buf)
for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
if (ap->pat != NULL && ap->cmds != NULL
&& (ap->buflocal_nr == 0
- ? match_file_pat(NULL, ap->reg_prog,
- fname, sfname, tail, ap->allow_dirs)
+ ? match_file_pat(NULL, &ap->reg_prog, fname, sfname, tail,
+ ap->allow_dirs)
: buf != NULL && ap->buflocal_nr == buf->b_fnum
)) {
retval = TRUE;
@@ -7128,32 +7128,29 @@ theend:
return retval;
}
-
-
-/*
- * Try matching a filename with a "pattern" ("prog" is NULL), or use the
- * precompiled regprog "prog" ("pattern" is NULL). That avoids calling
- * vim_regcomp() often.
- * Used for autocommands and 'wildignore'.
- * Returns TRUE if there is a match, FALSE otherwise.
- */
-int
-match_file_pat (
- char_u *pattern, /* pattern to match with */
- regprog_T *prog, /* pre-compiled regprog or NULL */
- char_u *fname, /* full path of file name */
- char_u *sfname, /* short file name or NULL */
- char_u *tail, /* tail of path */
- int allow_dirs /* allow matching with dir */
-)
+/// Tries matching a filename with a "pattern" ("prog" is NULL), or use the
+/// precompiled regprog "prog" ("pattern" is NULL). That avoids calling
+/// vim_regcomp() often.
+///
+/// Used for autocommands and 'wildignore'.
+///
+/// @param pattern the pattern to match with
+/// @param prog the pre-compiled regprog or NULL
+/// @param fname the full path of the file name
+/// @param sfname the short file name or NULL
+/// @param tail the tail of the path
+/// @param allow_dirs allow matching with dir
+/// @return true if there is a match, false otherwise
+static bool match_file_pat(char_u *pattern, regprog_T **prog, char_u *fname,
+ char_u *sfname, char_u *tail, int allow_dirs)
{
regmatch_T regmatch;
- int result = FALSE;
+ bool result = false;
regmatch.rm_ic = p_fic; /* ignore case if 'fileignorecase' is set */
{
if (prog != NULL)
- regmatch.regprog = prog;
+ regmatch.regprog = *prog;
else
regmatch.regprog = vim_regcomp(pattern, RE_MAGIC);
}
@@ -7171,10 +7168,13 @@ match_file_pat (
|| (sfname != NULL
&& vim_regexec(&regmatch, sfname, (colnr_T)0))))
|| (!allow_dirs && vim_regexec(&regmatch, tail, (colnr_T)0)))))
- result = TRUE;
+ result = true;
- if (prog == NULL)
+ if (prog != NULL) {
+ *prog = regmatch.regprog;
+ } else {
vim_regfree(regmatch.regprog);
+ }
return result;
}
@@ -7189,7 +7189,7 @@ int match_file_list(char_u *list, char_u *sfname, char_u *ffname)
char_u *tail;
char_u *regpat;
char allow_dirs;
- int match;
+ bool match;
char_u *p;
tail = path_tail(sfname);
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 5cf2f4d5a7..a37a41caeb 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -561,7 +561,9 @@ restofline:
tail = NULL;
regmatch.regprog = fmt_ptr->prog;
- if (vim_regexec(&regmatch, IObuff, (colnr_T)0)) {
+ int r = vim_regexec(&regmatch, IObuff, (colnr_T)0);
+ fmt_ptr->prog = regmatch.regprog;
+ if (r) {
if ((idx == 'C' || idx == 'Z') && !multiline)
continue;
if (vim_strchr((char_u *)"EWI", idx) != NULL)
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index d9031ab78a..6726b49e77 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -7045,6 +7045,7 @@ static void report_re_switch(char_u *pat)
/// Matches a regexp against a string.
/// "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
+/// Note: "rmp->regprog" may be freed and changed.
/// Uses curbuf for line count and 'iskeyword'.
/// When "nl" is true consider a "\n" in "line" to be a line break.
///
@@ -7080,12 +7081,24 @@ static int vim_regexec_both(regmatch_T *rmp, char_u *line, colnr_T col, bool nl)
return result;
}
+// Note: "*prog" may be freed and changed.
+int vim_regexec_prog(regprog_T **prog, bool ignore_case, char_u *line,
+ colnr_T col)
+{
+ regmatch_T regmatch = {.regprog = *prog, .rm_ic = ignore_case};
+ int r = vim_regexec_both(&regmatch, line, col, false);
+ *prog = regmatch.regprog;
+ return r;
+}
+
+// Note: "rmp->regprog" may be freed and changed.
int vim_regexec(regmatch_T *rmp, char_u *line, colnr_T col)
{
return vim_regexec_both(rmp, line, col, false);
}
// Like vim_regexec(), but consider a "\n" in "line" to be a line break.
+// Note: "rmp->regprog" may be freed and changed.
int vim_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col)
{
return vim_regexec_both(rmp, line, col, true);
@@ -7094,6 +7107,7 @@ int vim_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col)
/*
* Match a regexp against multiple lines.
* "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
+ * Note: "rmp->regprog" may be freed and changed.
* Uses curbuf for line count and 'iskeyword'.
*
* Return zero if there is no match. Return number of lines contained in the
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 06cba3b324..faddfedb89 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -1201,8 +1201,11 @@ spell_check (
// Check for end of sentence.
regmatch.regprog = wp->w_s->b_cap_prog;
regmatch.rm_ic = FALSE;
- if (vim_regexec(&regmatch, ptr, 0))
+ int r = vim_regexec(&regmatch, ptr, 0);
+ wp->w_s->b_cap_prog = regmatch.regprog;
+ if (r) {
*capcol = (int)(regmatch.endp[0] - ptr);
+ }
}
if (has_mbyte) {
@@ -1733,7 +1736,6 @@ match_checkcompoundpattern (
// does not have too many syllables.
static bool can_compound(slang_T *slang, char_u *word, char_u *flags)
{
- regmatch_T regmatch;
char_u uflags[MAXWLEN * 2];
int i;
char_u *p;
@@ -1749,9 +1751,7 @@ static bool can_compound(slang_T *slang, char_u *word, char_u *flags)
p = uflags;
} else
p = flags;
- regmatch.regprog = slang->sl_compprog;
- regmatch.rm_ic = FALSE;
- if (!vim_regexec(&regmatch, p, 0))
+ if (!vim_regexec_prog(&slang->sl_compprog, false, p, 0))
return false;
// Count the number of syllables. This may be slow, do it last. If there
@@ -1850,8 +1850,6 @@ valid_word_prefix (
{
int prefcnt;
int pidx;
- regprog_T *rp;
- regmatch_T regmatch;
int prefid;
prefid = (unsigned)flags >> 24;
@@ -1869,12 +1867,11 @@ valid_word_prefix (
// Check the condition, if there is one. The condition index is
// stored in the two bytes above the prefix ID byte.
- rp = slang->sl_prefprog[((unsigned)pidx >> 8) & 0xffff];
- if (rp != NULL) {
- regmatch.regprog = rp;
- regmatch.rm_ic = FALSE;
- if (!vim_regexec(&regmatch, word, 0))
+ regprog_T **rp = &slang->sl_prefprog[((unsigned)pidx >> 8) & 0xffff];
+ if (*rp != NULL) {
+ if (!vim_regexec_prog(rp, false, word, 0)) {
continue;
+ }
} else if (cond_req)
continue;
@@ -5670,7 +5667,6 @@ store_aff_word (
hashitem_T *hi;
affheader_T *ah;
affentry_T *ae;
- regmatch_T regmatch;
char_u newword[MAXWLEN];
int retval = OK;
int i, j;
@@ -5707,15 +5703,13 @@ store_aff_word (
// When a previously added affix had CIRCUMFIX this one
// must have it too, if it had not then this one must not
// have one either.
- regmatch.regprog = ae->ae_prog;
- regmatch.rm_ic = FALSE;
if ((xht != NULL || !affile->af_pfxpostpone
|| ae->ae_chop != NULL
|| ae->ae_flags != NULL)
&& (ae->ae_chop == NULL
|| STRLEN(ae->ae_chop) < wordlen)
&& (ae->ae_prog == NULL
- || vim_regexec(&regmatch, word, (colnr_T)0))
+ || vim_regexec_prog(&ae->ae_prog, false, word, (colnr_T)0))
&& (((condit & CONDIT_CFIX) == 0)
== ((condit & CONDIT_AFF) == 0
|| ae->ae_flags == NULL
@@ -8636,6 +8630,7 @@ static bool check_need_cap(linenr_T lnum, colnr_T col)
break;
}
}
+ curwin->w_s->b_cap_prog = regmatch.regprog;
}
xfree(line_copy);
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index 2df0e72f8f..ec54887246 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -827,8 +827,10 @@ static int syn_match_linecont(linenr_T lnum)
if (syn_block->b_syn_linecont_prog != NULL) {
regmatch.rmm_ic = syn_block->b_syn_linecont_ic;
regmatch.regprog = syn_block->b_syn_linecont_prog;
- return syn_regexec(&regmatch, lnum, (colnr_T)0,
- IF_SYN_TIME(&syn_block->b_syn_linecont_time));
+ int r = syn_regexec(&regmatch, lnum, (colnr_T)0,
+ IF_SYN_TIME(&syn_block->b_syn_linecont_time));
+ syn_block->b_syn_linecont_prog = regmatch.regprog;
+ return r;
}
return FALSE;
}
@@ -1798,10 +1800,10 @@ syn_current_attr (
regmatch.rmm_ic = spp->sp_ic;
regmatch.regprog = spp->sp_prog;
- if (!syn_regexec(&regmatch,
- current_lnum,
- (colnr_T)lc_col,
- IF_SYN_TIME(&spp->sp_time))) {
+ int r = syn_regexec(&regmatch, current_lnum, (colnr_T)lc_col,
+ IF_SYN_TIME(&spp->sp_time));
+ spp->sp_prog = regmatch.regprog;
+ if (!r) {
/* no match in this line, try another one */
spp->sp_startcol = MAXCOL;
continue;
@@ -2585,8 +2587,10 @@ find_endpos (
regmatch.rmm_ic = spp->sp_ic;
regmatch.regprog = spp->sp_prog;
- if (syn_regexec(&regmatch, startpos->lnum, lc_col,
- IF_SYN_TIME(&spp->sp_time))) {
+ int r = syn_regexec(&regmatch, startpos->lnum, lc_col,
+ IF_SYN_TIME(&spp->sp_time));
+ spp->sp_prog = regmatch.regprog;
+ if (r) {
if (best_idx == -1 || regmatch.startpos[0].col
< best_regmatch.startpos[0].col) {
best_idx = idx;
@@ -2614,10 +2618,10 @@ find_endpos (
lc_col = 0;
regmatch.rmm_ic = spp_skip->sp_ic;
regmatch.regprog = spp_skip->sp_prog;
- if (syn_regexec(&regmatch, startpos->lnum, lc_col,
- IF_SYN_TIME(&spp_skip->sp_time))
- && regmatch.startpos[0].col
- <= best_regmatch.startpos[0].col) {
+ int r = syn_regexec(&regmatch, startpos->lnum, lc_col,
+ IF_SYN_TIME(&spp_skip->sp_time));
+ spp_skip->sp_prog = regmatch.regprog;
+ if (r && regmatch.startpos[0].col <= best_regmatch.startpos[0].col) {
/* Add offset to skip pattern match */
syn_add_end_off(&pos, &regmatch, spp_skip, SPO_ME_OFF, 1);
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 44adad70e0..d4c2a42250 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -215,7 +215,7 @@ static int included_patches[] = {
//557 NA
//556 NA
//555 NA
- //554,
+ 554,
553,
552,
551,
@@ -250,7 +250,7 @@ static int included_patches[] = {
//522 NA
521,
520,
- //519,
+ 519,
518,
517,
516,