diff src/buffer.c @ 6375:27a36d1013a6 v7.4.519

updated for version 7.4.519 Problem: Crash when using syntax highlighting. Solution: When regprog is freed and replaced, store the result.
author Bram Moolenaar <bram@vim.org>
date Wed, 19 Nov 2014 16:38:07 +0100
parents 54194bd6ed60
children b5df99582638
line wrap: on
line diff
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -28,9 +28,9 @@
 #include "vim.h"
 
 #if defined(FEAT_CMDL_COMPL) || defined(FEAT_LISTCMDS) || defined(FEAT_EVAL) || defined(FEAT_PERL)
-static char_u	*buflist_match __ARGS((regprog_T *prog, buf_T *buf, int ignore_case));
+static char_u	*buflist_match __ARGS((regmatch_T *rmp, buf_T *buf, int ignore_case));
 # define HAVE_BUFLIST_MATCH
-static char_u	*fname_match __ARGS((regprog_T *prog, char_u *name, int ignore_case));
+static char_u	*fname_match __ARGS((regmatch_T *rmp, char_u *name, int ignore_case));
 #endif
 static void	buflist_setfpos __ARGS((buf_T *buf, win_T *win, linenr_T lnum, colnr_T col, int copy_options));
 static wininfo_T *find_wininfo __ARGS((buf_T *buf, int skip_diff_buffer));
@@ -2220,7 +2220,6 @@ buflist_findpat(pattern, pattern_end, un
     int		curtab_only;	/* find buffers in current tab only */
 {
     buf_T	*buf;
-    regprog_T	*prog;
     int		match = -1;
     int		find_listed;
     char_u	*pat;
@@ -2265,14 +2264,16 @@ buflist_findpat(pattern, pattern_end, un
 	{
 	    for (attempt = 0; attempt <= 3; ++attempt)
 	    {
+		regmatch_T	regmatch;
+
 		/* may add '^' and '$' */
 		if (toggledollar)
 		    *patend = (attempt < 2) ? NUL : '$'; /* add/remove '$' */
 		p = pat;
 		if (*p == '^' && !(attempt & 1))	 /* add/remove '^' */
 		    ++p;
-		prog = vim_regcomp(p, p_magic ? RE_MAGIC : 0);
-		if (prog == NULL)
+		regmatch.regprog = vim_regcomp(p, p_magic ? RE_MAGIC : 0);
+		if (regmatch.regprog == NULL)
 		{
 		    vim_free(pat);
 		    return -1;
@@ -2283,7 +2284,7 @@ buflist_findpat(pattern, pattern_end, un
 #ifdef FEAT_DIFF
 			    && (!diffmode || diff_mode_buf(buf))
 #endif
-			    && buflist_match(prog, buf, FALSE) != NULL)
+			    && buflist_match(&regmatch, buf, FALSE) != NULL)
 		    {
 			if (curtab_only)
 			{
@@ -2310,7 +2311,7 @@ buflist_findpat(pattern, pattern_end, un
 			match = buf->b_fnum;	/* remember first match */
 		    }
 
-		vim_regfree(prog);
+		vim_regfree(regmatch.regprog);
 		if (match >= 0)			/* found one match */
 		    break;
 	    }
@@ -2352,7 +2353,6 @@ ExpandBufnames(pat, num_file, file, opti
     int		round;
     char_u	*p;
     int		attempt;
-    regprog_T	*prog;
     char_u	*patc;
 
     *num_file = 0;		    /* return values in case of FAIL */
@@ -2376,10 +2376,12 @@ ExpandBufnames(pat, num_file, file, opti
      */
     for (attempt = 0; attempt <= 1; ++attempt)
     {
+	regmatch_T	regmatch;
+
 	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.regprog = vim_regcomp(patc + attempt * 11, RE_MAGIC);
+	if (regmatch.regprog == NULL)
 	{
 	    if (patc != pat)
 		vim_free(patc);
@@ -2397,7 +2399,7 @@ ExpandBufnames(pat, num_file, file, opti
 	    {
 		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)
@@ -2419,14 +2421,14 @@ ExpandBufnames(pat, num_file, file, opti
 		*file = (char_u **)alloc((unsigned)(count * sizeof(char_u *)));
 		if (*file == NULL)
 		{
-		    vim_regfree(prog);
+		    vim_regfree(regmatch.regprog);
 		    if (patc != pat)
 			vim_free(patc);
 		    return FAIL;
 		}
 	    }
 	}
-	vim_regfree(prog);
+	vim_regfree(regmatch.regprog);
 	if (count)		/* match(es) found, break here */
 	    break;
     }
@@ -2445,17 +2447,17 @@ ExpandBufnames(pat, num_file, file, opti
  * Check for a match on the file name for buffer "buf" with regprog "prog".
  */
     static char_u *
-buflist_match(prog, buf, ignore_case)
-    regprog_T	*prog;
+buflist_match(rmp, buf, ignore_case)
+    regmatch_T	*rmp;
     buf_T	*buf;
     int		ignore_case;  /* when TRUE ignore case, when FALSE use 'fic' */
 {
     char_u	*match;
 
     /* First try the short file name, then the long file name. */
-    match = fname_match(prog, buf->b_sfname, ignore_case);
+    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;
 }
@@ -2465,27 +2467,25 @@ buflist_match(prog, buf, ignore_case)
  * Return "name" when there is a match, NULL when not.
  */
     static char_u *
-fname_match(prog, name, ignore_case)
-    regprog_T	*prog;
+fname_match(rmp, name, ignore_case)
+    regmatch_T	*rmp;
     char_u	*name;
     int		ignore_case;  /* when TRUE ignore case, when FALSE use 'fic' */
 {
     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 (p != NULL && vim_regexec(&regmatch, p, (colnr_T)0))
+	    if (p != NULL && vim_regexec(rmp, p, (colnr_T)0))
 		match = name;
 	    vim_free(p);
 	}