[vim] - patchlevel 1090

Karsten Hopp karsten at fedoraproject.org
Tue Jun 4 10:14:43 UTC 2013


commit 3d1a0d1d02cb354d8effd8b52cf44578d31850ca
Author: Karsten Hopp <karsten at redhat.com>
Date:   Tue Jun 4 12:06:48 2013 +0200

    - patchlevel 1090

 7.3.1090 | 1893 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1893 insertions(+), 0 deletions(-)
---
diff --git a/7.3.1090 b/7.3.1090
new file mode 100644
index 0000000..1278fae
--- /dev/null
+++ b/7.3.1090
@@ -0,0 +1,1893 @@
+To: vim_dev at googlegroups.com
+Subject: Patch 7.3.10
+Fcc: outbox
+From: Bram Moolenaar <Bram at moolenaar.net>
+Mime-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+------------
+
+Patch 7.3.1090
+Problem:    New regexp engine does not support \z1 .. \z9 and \z(.
+Solution:   Implement the syntax submatches.
+Files:	    src/regexp.h, src/regexp_nfa.c
+
+
+*** ../vim-7.3.1089/src/regexp.h	2013-05-30 17:05:34.000000000 +0200
+--- src/regexp.h	2013-06-01 22:18:07.000000000 +0200
+***************
+*** 55,61 ****
+--- 55,63 ----
+      char_u		reganch;
+      char_u		*regmust;
+      int			regmlen;
++ #ifdef FEAT_SYN_HL
+      char_u		reghasz;
++ #endif
+      char_u		program[1];	/* actually longer.. */
+  } bt_regprog_T;
+  
+***************
+*** 88,93 ****
+--- 90,98 ----
+      nfa_state_T		*start;
+      int			has_zend;	/* pattern contains \ze */
+      int			has_backref;	/* pattern contains \1 .. \9 */
++ #ifdef FEAT_SYN_HL
++     int			reghasz;
++ #endif
+      int			nsubexp;	/* number of () */
+      int			nstate;
+      nfa_state_T		state[0];	/* actually longer.. */
+*** ../vim-7.3.1089/src/regexp_nfa.c	2013-06-01 19:54:39.000000000 +0200
+--- src/regexp_nfa.c	2013-06-01 22:54:08.000000000 +0200
+***************
+*** 78,90 ****
+      NFA_BACKREF7,		    /* \7 */
+      NFA_BACKREF8,		    /* \8 */
+      NFA_BACKREF9,		    /* \9 */
+      NFA_SKIP,			    /* Skip characters */
+  
+      NFA_MOPEN,
+!     NFA_MCLOSE = NFA_MOPEN + NSUBEXP,
+  
+      /* NFA_FIRST_NL */
+!     NFA_ANY = NFA_MCLOSE + NSUBEXP, /*	Match any one character. */
+      NFA_ANYOF,		/*	Match any character in this string. */
+      NFA_ANYBUT,		/*	Match any character not in this string. */
+      NFA_IDENT,		/*	Match identifier char */
+--- 78,144 ----
+      NFA_BACKREF7,		    /* \7 */
+      NFA_BACKREF8,		    /* \8 */
+      NFA_BACKREF9,		    /* \9 */
++ #ifdef FEAT_SYN_HL
++     NFA_ZREF1,			    /* \z1 */
++     NFA_ZREF2,			    /* \z2 */
++     NFA_ZREF3,			    /* \z3 */
++     NFA_ZREF4,			    /* \z4 */
++     NFA_ZREF5,			    /* \z5 */
++     NFA_ZREF6,			    /* \z6 */
++     NFA_ZREF7,			    /* \z7 */
++     NFA_ZREF8,			    /* \z8 */
++     NFA_ZREF9,			    /* \z9 */
++ #endif
+      NFA_SKIP,			    /* Skip characters */
+  
+      NFA_MOPEN,
+!     NFA_MOPEN1,
+!     NFA_MOPEN2,
+!     NFA_MOPEN3,
+!     NFA_MOPEN4,
+!     NFA_MOPEN5,
+!     NFA_MOPEN6,
+!     NFA_MOPEN7,
+!     NFA_MOPEN8,
+!     NFA_MOPEN9,
+! 
+!     NFA_MCLOSE,
+!     NFA_MCLOSE1,
+!     NFA_MCLOSE2,
+!     NFA_MCLOSE3,
+!     NFA_MCLOSE4,
+!     NFA_MCLOSE5,
+!     NFA_MCLOSE6,
+!     NFA_MCLOSE7,
+!     NFA_MCLOSE8,
+!     NFA_MCLOSE9,
+! 
+! #ifdef FEAT_SYN_HL
+!     NFA_ZOPEN,
+!     NFA_ZOPEN1,
+!     NFA_ZOPEN2,
+!     NFA_ZOPEN3,
+!     NFA_ZOPEN4,
+!     NFA_ZOPEN5,
+!     NFA_ZOPEN6,
+!     NFA_ZOPEN7,
+!     NFA_ZOPEN8,
+!     NFA_ZOPEN9,
+! 
+!     NFA_ZCLOSE,
+!     NFA_ZCLOSE1,
+!     NFA_ZCLOSE2,
+!     NFA_ZCLOSE3,
+!     NFA_ZCLOSE4,
+!     NFA_ZCLOSE5,
+!     NFA_ZCLOSE6,
+!     NFA_ZCLOSE7,
+!     NFA_ZCLOSE8,
+!     NFA_ZCLOSE9,
+! #endif
+  
+      /* NFA_FIRST_NL */
+!     NFA_ANY,		/*	Match any one character. */
+      NFA_ANYOF,		/*	Match any character in this string. */
+      NFA_ANYBUT,		/*	Match any character not in this string. */
+      NFA_IDENT,		/*	Match identifier char */
+***************
+*** 221,227 ****
+  static void nfa_save_listids __ARGS((nfa_state_T *start, int *list));
+  static void nfa_restore_listids __ARGS((nfa_state_T *start, int *list));
+  static int nfa_re_num_cmp __ARGS((long_u val, int op, long_u pos));
+! static long nfa_regtry __ARGS((nfa_state_T *start, colnr_T col));
+  static long nfa_regexec_both __ARGS((char_u *line, colnr_T col));
+  static regprog_T *nfa_regcomp __ARGS((char_u *expr, int re_flags));
+  static int nfa_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
+--- 275,281 ----
+  static void nfa_save_listids __ARGS((nfa_state_T *start, int *list));
+  static void nfa_restore_listids __ARGS((nfa_state_T *start, int *list));
+  static int nfa_re_num_cmp __ARGS((long_u val, int op, long_u pos));
+! static long nfa_regtry __ARGS((nfa_regprog_T *prog, colnr_T col));
+  static long nfa_regexec_both __ARGS((char_u *line, colnr_T col));
+  static regprog_T *nfa_regcomp __ARGS((char_u *expr, int re_flags));
+  static int nfa_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
+***************
+*** 267,272 ****
+--- 321,327 ----
+      nfa_has_zend = FALSE;
+      nfa_has_backref = FALSE;
+  
++     /* shared with BT engine */
+      regcomp_start(expr, re_flags);
+  
+      return OK;
+***************
+*** 799,804 ****
+--- 854,860 ----
+  		    EMIT(NFA_ZEND);
+  		    nfa_has_zend = TRUE;
+  		    break;
++ #ifdef FEAT_SYN_HL
+  		case '1':
+  		case '2':
+  		case '3':
+***************
+*** 808,816 ****
+  		case '7':
+  		case '8':
+  		case '9':
+  		case '(':
+! 		    /* TODO: \z1...\z9 and \z( not yet supported */
+! 		    return FAIL;
+  		default:
+  		    syntax_error = TRUE;
+  		    EMSGN(_("E867: (NFA) Unknown operator '\\z%c'"),
+--- 864,882 ----
+  		case '7':
+  		case '8':
+  		case '9':
++ 		    /* \z1...\z9 */
++ 		    EMIT(NFA_ZREF1 + (no_Magic(c) - '1'));
++ 		    /* No need to set nfa_has_backref, the sub-matches don't
++ 		     * change when \z1 .. \z9 maches or not. */
++ 		    re_has_z = REX_USE;
++ 		    break;
+  		case '(':
+! 		    /* \z(  */
+! 		    if (nfa_reg(REG_ZPAREN) == FAIL)
+! 			return FAIL;	    /* cascaded error */
+! 		    re_has_z = REX_SET;
+! 		    break;
+! #endif
+  		default:
+  		    syntax_error = TRUE;
+  		    EMSGN(_("E867: (NFA) Unknown operator '\\z%c'"),
+***************
+*** 1651,1658 ****
+  {
+      int		parno = 0;
+  
+- #ifdef FEAT_SYN_HL
+- #endif
+      if (paren == REG_PAREN)
+      {
+  	if (regnpar >= NSUBEXP) /* Too many `(' */
+--- 1717,1722 ----
+***************
+*** 1662,1667 ****
+--- 1726,1743 ----
+  	}
+  	parno = regnpar++;
+      }
++ #ifdef FEAT_SYN_HL
++     else if (paren == REG_ZPAREN)
++     {
++ 	/* Make a ZOPEN node. */
++ 	if (regnzpar >= NSUBEXP)
++ 	{
++ 	    syntax_error = TRUE;
++ 	    EMSG_RET_FAIL(_("E879: (NFA regexp) Too many \\z("));
++ 	}
++ 	parno = regnzpar++;
++     }
++ #endif
+  
+      if (nfa_regbranch() == FAIL)
+  	return FAIL;	    /* cascaded error */
+***************
+*** 1700,1705 ****
+--- 1776,1785 ----
+  	had_endbrace[parno] = TRUE;     /* have seen the close paren */
+  	EMIT(NFA_MOPEN + parno);
+      }
++ #ifdef FEAT_SYN_HL
++     else if (paren == REG_ZPAREN)
++ 	EMIT(NFA_ZOPEN + parno);
++ #endif
+  
+      return OK;
+  }
+***************
+*** 1738,1743 ****
+--- 1818,1834 ----
+  	case NFA_BACKREF7:  STRCPY(code, "NFA_BACKREF7"); break;
+  	case NFA_BACKREF8:  STRCPY(code, "NFA_BACKREF8"); break;
+  	case NFA_BACKREF9:  STRCPY(code, "NFA_BACKREF9"); break;
++ #ifdef FEAT_SYN_HL
++ 	case NFA_ZREF1:	    STRCPY(code, "NFA_ZREF1"); break;
++ 	case NFA_ZREF2:	    STRCPY(code, "NFA_ZREF2"); break;
++ 	case NFA_ZREF3:	    STRCPY(code, "NFA_ZREF3"); break;
++ 	case NFA_ZREF4:	    STRCPY(code, "NFA_ZREF4"); break;
++ 	case NFA_ZREF5:	    STRCPY(code, "NFA_ZREF5"); break;
++ 	case NFA_ZREF6:	    STRCPY(code, "NFA_ZREF6"); break;
++ 	case NFA_ZREF7:	    STRCPY(code, "NFA_ZREF7"); break;
++ 	case NFA_ZREF8:	    STRCPY(code, "NFA_ZREF8"); break;
++ 	case NFA_ZREF9:	    STRCPY(code, "NFA_ZREF9"); break;
++ #endif
+  	case NFA_SKIP:	    STRCPY(code, "NFA_SKIP"); break;
+  
+  	case NFA_PREV_ATOM_NO_WIDTH:
+***************
+*** 1758,1789 ****
+  	case NFA_COMPOSING:	    STRCPY(code, "NFA_COMPOSING"); break;
+  	case NFA_END_COMPOSING:	    STRCPY(code, "NFA_END_COMPOSING"); break;
+  
+! 	case NFA_MOPEN + 0:
+! 	case NFA_MOPEN + 1:
+! 	case NFA_MOPEN + 2:
+! 	case NFA_MOPEN + 3:
+! 	case NFA_MOPEN + 4:
+! 	case NFA_MOPEN + 5:
+! 	case NFA_MOPEN + 6:
+! 	case NFA_MOPEN + 7:
+! 	case NFA_MOPEN + 8:
+! 	case NFA_MOPEN + 9:
+  	    STRCPY(code, "NFA_MOPEN(x)");
+  	    code[10] = c - NFA_MOPEN + '0';
+  	    break;
+! 	case NFA_MCLOSE + 0:
+! 	case NFA_MCLOSE + 1:
+! 	case NFA_MCLOSE + 2:
+! 	case NFA_MCLOSE + 3:
+! 	case NFA_MCLOSE + 4:
+! 	case NFA_MCLOSE + 5:
+! 	case NFA_MCLOSE + 6:
+! 	case NFA_MCLOSE + 7:
+! 	case NFA_MCLOSE + 8:
+! 	case NFA_MCLOSE + 9:
+  	    STRCPY(code, "NFA_MCLOSE(x)");
+  	    code[11] = c - NFA_MCLOSE + '0';
+  	    break;
+  	case NFA_EOL:		STRCPY(code, "NFA_EOL "); break;
+  	case NFA_BOL:		STRCPY(code, "NFA_BOL "); break;
+  	case NFA_EOW:		STRCPY(code, "NFA_EOW "); break;
+--- 1849,1908 ----
+  	case NFA_COMPOSING:	    STRCPY(code, "NFA_COMPOSING"); break;
+  	case NFA_END_COMPOSING:	    STRCPY(code, "NFA_END_COMPOSING"); break;
+  
+! 	case NFA_MOPEN:
+! 	case NFA_MOPEN1:
+! 	case NFA_MOPEN2:
+! 	case NFA_MOPEN3:
+! 	case NFA_MOPEN4:
+! 	case NFA_MOPEN5:
+! 	case NFA_MOPEN6:
+! 	case NFA_MOPEN7:
+! 	case NFA_MOPEN8:
+! 	case NFA_MOPEN9:
+  	    STRCPY(code, "NFA_MOPEN(x)");
+  	    code[10] = c - NFA_MOPEN + '0';
+  	    break;
+! 	case NFA_MCLOSE:
+! 	case NFA_MCLOSE1:
+! 	case NFA_MCLOSE2:
+! 	case NFA_MCLOSE3:
+! 	case NFA_MCLOSE4:
+! 	case NFA_MCLOSE5:
+! 	case NFA_MCLOSE6:
+! 	case NFA_MCLOSE7:
+! 	case NFA_MCLOSE8:
+! 	case NFA_MCLOSE9:
+  	    STRCPY(code, "NFA_MCLOSE(x)");
+  	    code[11] = c - NFA_MCLOSE + '0';
+  	    break;
++ #ifdef FEAT_SYN_HL
++ 	case NFA_ZOPEN:
++ 	case NFA_ZOPEN1:
++ 	case NFA_ZOPEN2:
++ 	case NFA_ZOPEN3:
++ 	case NFA_ZOPEN4:
++ 	case NFA_ZOPEN5:
++ 	case NFA_ZOPEN6:
++ 	case NFA_ZOPEN7:
++ 	case NFA_ZOPEN8:
++ 	case NFA_ZOPEN9:
++ 	    STRCPY(code, "NFA_ZOPEN(x)");
++ 	    code[10] = c - NFA_ZOPEN + '0';
++ 	    break;
++ 	case NFA_ZCLOSE:
++ 	case NFA_ZCLOSE1:
++ 	case NFA_ZCLOSE2:
++ 	case NFA_ZCLOSE3:
++ 	case NFA_ZCLOSE4:
++ 	case NFA_ZCLOSE5:
++ 	case NFA_ZCLOSE6:
++ 	case NFA_ZCLOSE7:
++ 	case NFA_ZCLOSE8:
++ 	case NFA_ZCLOSE9:
++ 	    STRCPY(code, "NFA_ZCLOSE(x)");
++ 	    code[11] = c - NFA_ZCLOSE + '0';
++ 	    break;
++ #endif
+  	case NFA_EOL:		STRCPY(code, "NFA_EOL "); break;
+  	case NFA_BOL:		STRCPY(code, "NFA_BOL "); break;
+  	case NFA_EOW:		STRCPY(code, "NFA_EOW "); break;
+***************
+*** 2437,2453 ****
+  	    /* FALLTHROUGH */
+  #endif
+  
+! 	case NFA_MOPEN + 0:	/* Submatch */
+! 	case NFA_MOPEN + 1:
+! 	case NFA_MOPEN + 2:
+! 	case NFA_MOPEN + 3:
+! 	case NFA_MOPEN + 4:
+! 	case NFA_MOPEN + 5:
+! 	case NFA_MOPEN + 6:
+! 	case NFA_MOPEN + 7:
+! 	case NFA_MOPEN + 8:
+! 	case NFA_MOPEN + 9:
+! 	case NFA_NOPEN:		/* \%( "Invisible Submatch" */
+  	    if (nfa_calc_size == TRUE)
+  	    {
+  		nstate += 2;
+--- 2556,2584 ----
+  	    /* FALLTHROUGH */
+  #endif
+  
+! 	case NFA_MOPEN:	/* \( \) Submatch */
+! 	case NFA_MOPEN1:
+! 	case NFA_MOPEN2:
+! 	case NFA_MOPEN3:
+! 	case NFA_MOPEN4:
+! 	case NFA_MOPEN5:
+! 	case NFA_MOPEN6:
+! 	case NFA_MOPEN7:
+! 	case NFA_MOPEN8:
+! 	case NFA_MOPEN9:
+! #ifdef FEAT_SYN_HL
+! 	case NFA_ZOPEN:	/* \z( \) Submatch */
+! 	case NFA_ZOPEN1:
+! 	case NFA_ZOPEN2:
+! 	case NFA_ZOPEN3:
+! 	case NFA_ZOPEN4:
+! 	case NFA_ZOPEN5:
+! 	case NFA_ZOPEN6:
+! 	case NFA_ZOPEN7:
+! 	case NFA_ZOPEN8:
+! 	case NFA_ZOPEN9:
+! #endif
+! 	case NFA_NOPEN:	/* \%( \) "Invisible Submatch" */
+  	    if (nfa_calc_size == TRUE)
+  	    {
+  		nstate += 2;
+***************
+*** 2457,2472 ****
+  	    mopen = *p;
+  	    switch (*p)
+  	    {
+! 		case NFA_NOPEN:
+! 		    mclose = NFA_NCLOSE;
+! 		    break;
+  #ifdef FEAT_MBYTE
+! 		case NFA_COMPOSING:
+! 		    mclose = NFA_END_COMPOSING;
+! 		    break;
+  #endif
+  		default:
+! 		    /* NFA_MOPEN(0) ... NFA_MOPEN(9) */
+  		    mclose = *p + NSUBEXP;
+  		    break;
+  	    }
+--- 2588,2611 ----
+  	    mopen = *p;
+  	    switch (*p)
+  	    {
+! 		case NFA_NOPEN: mclose = NFA_NCLOSE; break;
+! #ifdef FEAT_SYN_HL
+! 		case NFA_ZOPEN: mclose = NFA_ZCLOSE; break;
+! 		case NFA_ZOPEN1: mclose = NFA_ZCLOSE1; break;
+! 		case NFA_ZOPEN2: mclose = NFA_ZCLOSE2; break;
+! 		case NFA_ZOPEN3: mclose = NFA_ZCLOSE3; break;
+! 		case NFA_ZOPEN4: mclose = NFA_ZCLOSE4; break;
+! 		case NFA_ZOPEN5: mclose = NFA_ZCLOSE5; break;
+! 		case NFA_ZOPEN6: mclose = NFA_ZCLOSE6; break;
+! 		case NFA_ZOPEN7: mclose = NFA_ZCLOSE7; break;
+! 		case NFA_ZOPEN8: mclose = NFA_ZCLOSE8; break;
+! 		case NFA_ZOPEN9: mclose = NFA_ZCLOSE9; break;
+! #endif
+  #ifdef FEAT_MBYTE
+! 		case NFA_COMPOSING: mclose = NFA_END_COMPOSING; break;
+  #endif
+  		default:
+! 		    /* NFA_MOPEN, NFA_MOPEN1 .. NFA_MOPEN9 */
+  		    mclose = *p + NSUBEXP;
+  		    break;
+  	    }
+***************
+*** 2518,2523 ****
+--- 2657,2673 ----
+  	case NFA_BACKREF7:
+  	case NFA_BACKREF8:
+  	case NFA_BACKREF9:
++ #ifdef FEAT_SYN_HL
++ 	case NFA_ZREF1:
++ 	case NFA_ZREF2:
++ 	case NFA_ZREF3:
++ 	case NFA_ZREF4:
++ 	case NFA_ZREF5:
++ 	case NFA_ZREF6:
++ 	case NFA_ZREF7:
++ 	case NFA_ZREF8:
++ 	case NFA_ZREF9:
++ #endif
+  	    if (nfa_calc_size == TRUE)
+  	    {
+  		nstate += 2;
+***************
+*** 2630,2641 ****
+      } list;
+  } regsub_T;
+  
+  /* nfa_thread_T contains execution information of a NFA state */
+  typedef struct
+  {
+      nfa_state_T	*state;
+      int		count;
+!     regsub_T	sub;		/* submatch info, only party used */
+  } nfa_thread_T;
+  
+  /* nfa_list_T contains the alternative NFA execution states. */
+--- 2780,2799 ----
+      } list;
+  } regsub_T;
+  
++ typedef struct
++ {
++     regsub_T	norm; /* \( .. \) matches */
++ #ifdef FEAT_SYN_HL
++     regsub_T	synt; /* \z( .. \) matches */
++ #endif
++ } regsubs_T;
++ 
+  /* nfa_thread_T contains execution information of a NFA state */
+  typedef struct
+  {
+      nfa_state_T	*state;
+      int		count;
+!     regsubs_T	subs;		/* submatch info, only party used */
+  } nfa_thread_T;
+  
+  /* nfa_list_T contains the alternative NFA execution states. */
+***************
+*** 2648,2653 ****
+--- 2806,2824 ----
+  } nfa_list_T;
+  
+  #ifdef ENABLE_LOG
++ static void log_subsexpr __ARGS((regsubs_T *subs));
++ static void log_subexpr __ARGS((regsub_T *sub));
++ 
++     static void
++ log_subsexpr(subs)
++     regsubs_T *subs;
++ {
++     log_subexpr(&subs->norm);
++ # ifdef FEAT_SYN_HL
++     log_subexpr(&subs->synt);
++ # endif
++ }
++ 
+      static void
+  log_subexpr(sub)
+      regsub_T *sub;
+***************
+*** 2674,2682 ****
+  /* Used during execution: whether a match has been found. */
+  static int nfa_match;
+  
+  static int sub_equal __ARGS((regsub_T *sub1, regsub_T *sub2));
+! static void addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsub_T *sub, int off));
+! static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state, regsub_T *sub, int *ip));
+  
+  /*
+   * Return TRUE if "sub1" and "sub2" have the same positions.
+--- 2845,2916 ----
+  /* Used during execution: whether a match has been found. */
+  static int nfa_match;
+  
++ static void clear_sub __ARGS((regsub_T *sub));
++ static void copy_sub __ARGS((regsub_T *to, regsub_T *from));
++ static void copy_sub_off __ARGS((regsub_T *to, regsub_T *from));
+  static int sub_equal __ARGS((regsub_T *sub1, regsub_T *sub2));
+! static void addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, int off));
+! static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, int *ip));
+! 
+!     static void
+! clear_sub(sub)
+!     regsub_T *sub;
+! {
+!     if (REG_MULTI)
+! 	/* Use 0xff to set lnum to -1 */
+! 	vim_memset(sub->list.multi, 0xff,
+! 				      sizeof(struct multipos) * nfa_nsubexpr);
+!     else
+! 	vim_memset(sub->list.line, 0, sizeof(struct linepos) * nfa_nsubexpr);
+!     sub->in_use = 0;
+! }
+! 
+! /*
+!  * Copy the submatches from "from" to "to".
+!  */
+!     static void
+! copy_sub(to, from)
+!     regsub_T	*to;
+!     regsub_T	*from;
+! {
+!     to->in_use = from->in_use;
+!     if (from->in_use > 0)
+!     {
+! 	/* Copy the match start and end positions. */
+! 	if (REG_MULTI)
+! 	    mch_memmove(&to->list.multi[0],
+! 			&from->list.multi[0],
+! 			sizeof(struct multipos) * from->in_use);
+! 	else
+! 	    mch_memmove(&to->list.line[0],
+! 			&from->list.line[0],
+! 			sizeof(struct linepos) * from->in_use);
+!     }
+! }
+! 
+! /*
+!  * Like copy_sub() but exclude the main match.
+!  */
+!     static void
+! copy_sub_off(to, from)
+!     regsub_T	*to;
+!     regsub_T	*from;
+! {
+!     if (to->in_use < from->in_use)
+! 	to->in_use = from->in_use;
+!     if (from->in_use > 1)
+!     {
+! 	/* Copy the match start and end positions. */
+! 	if (REG_MULTI)
+! 	    mch_memmove(&to->list.multi[1],
+! 			&from->list.multi[1],
+! 			sizeof(struct multipos) * (from->in_use - 1));
+! 	else
+! 	    mch_memmove(&to->list.line[1],
+! 			&from->list.line[1],
+! 			sizeof(struct linepos) * (from->in_use - 1));
+!     }
+! }
+  
+  /*
+   * Return TRUE if "sub1" and "sub2" have the same positions.
+***************
+*** 2761,2770 ****
+  }
+  
+      static void
+! addstate(l, state, sub, off)
+      nfa_list_T		*l;	/* runtime state list */
+      nfa_state_T		*state;	/* state to update */
+!     regsub_T		*sub;	/* pointers to subexpressions */
+      int			off;	/* byte offset, when -1 go to next line */
+  {
+      int			subidx;
+--- 2995,3004 ----
+  }
+  
+      static void
+! addstate(l, state, subs, off)
+      nfa_list_T		*l;	/* runtime state list */
+      nfa_state_T		*state;	/* state to update */
+!     regsubs_T		*subs;	/* pointers to subexpressions */
+      int			off;	/* byte offset, when -1 go to next line */
+  {
+      int			subidx;
+***************
+*** 2773,2778 ****
+--- 3007,3013 ----
+      int			save_in_use;
+      char_u		*save_ptr;
+      int			i;
++     regsub_T		*sub;
+  #ifdef ENABLE_LOG
+      int			did_print = FALSE;
+  #endif
+***************
+*** 2787,2815 ****
+  	case NFA_NOPEN:
+  	case NFA_NCLOSE:
+  	case NFA_MCLOSE:
+! 	case NFA_MCLOSE + 1:
+! 	case NFA_MCLOSE + 2:
+! 	case NFA_MCLOSE + 3:
+! 	case NFA_MCLOSE + 4:
+! 	case NFA_MCLOSE + 5:
+! 	case NFA_MCLOSE + 6:
+! 	case NFA_MCLOSE + 7:
+! 	case NFA_MCLOSE + 8:
+! 	case NFA_MCLOSE + 9:
+  	    /* These nodes are not added themselves but their "out" and/or
+  	     * "out1" may be added below.  */
+  	    break;
+  
+  	case NFA_MOPEN:
+! 	case NFA_MOPEN + 1:
+! 	case NFA_MOPEN + 2:
+! 	case NFA_MOPEN + 3:
+! 	case NFA_MOPEN + 4:
+! 	case NFA_MOPEN + 5:
+! 	case NFA_MOPEN + 6:
+! 	case NFA_MOPEN + 7:
+! 	case NFA_MOPEN + 8:
+! 	case NFA_MOPEN + 9:
+  	    /* These nodes do not need to be added, but we need to bail out
+  	     * when it was tried to be added to this list before. */
+  	    if (state->lastlist == l->id)
+--- 3022,3074 ----
+  	case NFA_NOPEN:
+  	case NFA_NCLOSE:
+  	case NFA_MCLOSE:
+! 	case NFA_MCLOSE1:
+! 	case NFA_MCLOSE2:
+! 	case NFA_MCLOSE3:
+! 	case NFA_MCLOSE4:
+! 	case NFA_MCLOSE5:
+! 	case NFA_MCLOSE6:
+! 	case NFA_MCLOSE7:
+! 	case NFA_MCLOSE8:
+! 	case NFA_MCLOSE9:
+! #ifdef FEAT_SYN_HL
+! 	case NFA_ZCLOSE:
+! 	case NFA_ZCLOSE1:
+! 	case NFA_ZCLOSE2:
+! 	case NFA_ZCLOSE3:
+! 	case NFA_ZCLOSE4:
+! 	case NFA_ZCLOSE5:
+! 	case NFA_ZCLOSE6:
+! 	case NFA_ZCLOSE7:
+! 	case NFA_ZCLOSE8:
+! 	case NFA_ZCLOSE9:
+! #endif
+  	    /* These nodes are not added themselves but their "out" and/or
+  	     * "out1" may be added below.  */
+  	    break;
+  
+  	case NFA_MOPEN:
+! 	case NFA_MOPEN1:
+! 	case NFA_MOPEN2:
+! 	case NFA_MOPEN3:
+! 	case NFA_MOPEN4:
+! 	case NFA_MOPEN5:
+! 	case NFA_MOPEN6:
+! 	case NFA_MOPEN7:
+! 	case NFA_MOPEN8:
+! 	case NFA_MOPEN9:
+! #ifdef FEAT_SYN_HL
+! 	case NFA_ZOPEN:
+! 	case NFA_ZOPEN1:
+! 	case NFA_ZOPEN2:
+! 	case NFA_ZOPEN3:
+! 	case NFA_ZOPEN4:
+! 	case NFA_ZOPEN5:
+! 	case NFA_ZOPEN6:
+! 	case NFA_ZOPEN7:
+! 	case NFA_ZOPEN8:
+! 	case NFA_ZOPEN9:
+! #endif
+  	    /* These nodes do not need to be added, but we need to bail out
+  	     * when it was tried to be added to this list before. */
+  	    if (state->lastlist == l->id)
+***************
+*** 2839,2845 ****
+  		{
+  		    thread = &l->t[i];
+  		    if (thread->state->id == state->id
+! 					  && sub_equal(&thread->sub, sub))
+  			goto skip_add;
+  		}
+  	    }
+--- 3098,3108 ----
+  		{
+  		    thread = &l->t[i];
+  		    if (thread->state->id == state->id
+! 			    && sub_equal(&thread->subs.norm, &subs->norm)
+! #ifdef FEAT_SYN_HL
+! 			    && sub_equal(&thread->subs.synt, &subs->synt)
+! #endif
+! 					  )
+  			goto skip_add;
+  		}
+  	    }
+***************
+*** 2858,2876 ****
+  	    state->lastlist = l->id;
+  	    thread = &l->t[l->n++];
+  	    thread->state = state;
+! 	    thread->sub.in_use = sub->in_use;
+! 	    if (sub->in_use > 0)
+! 	    {
+! 		/* Copy the match start and end positions. */
+! 		if (REG_MULTI)
+! 		    mch_memmove(&thread->sub.list.multi[0],
+! 				&sub->list.multi[0],
+! 				sizeof(struct multipos) * sub->in_use);
+! 		else
+! 		    mch_memmove(&thread->sub.list.line[0],
+! 				&sub->list.line[0],
+! 				sizeof(struct linepos) * sub->in_use);
+! 	    }
+  #ifdef ENABLE_LOG
+  	    {
+  		int col;
+--- 3121,3130 ----
+  	    state->lastlist = l->id;
+  	    thread = &l->t[l->n++];
+  	    thread->state = state;
+! 	    copy_sub(&thread->subs.norm, &subs->norm);
+! #ifdef FEAT_SYN_HL
+! 	    copy_sub(&thread->subs.synt, &subs->synt);
+! #endif
+  #ifdef ENABLE_LOG
+  	    {
+  		int col;
+***************
+*** 2912,2959 ****
+  	    break;
+  
+  	case NFA_SPLIT:
+! 	    addstate(l, state->out, sub, off);
+! 	    addstate(l, state->out1, sub, off);
+  	    break;
+  
+- #if 0
+- 	case NFA_END_NEG_RANGE:
+- 	    /* Nothing to handle here. nfa_regmatch() will take care of it */
+- 	    break;
+- 
+- 	case NFA_NOT:
+- 	    EMSG(_("E999: (NFA regexp internal error) Should not process NOT node !"));
+- #ifdef ENABLE_LOG
+- 	fprintf(f, "\n\n>>> E999: Added state NFA_NOT to a list ... Something went wrong ! Why wasn't it processed already? \n\n");
+- #endif
+- 	    break;
+- 
+- 	case NFA_COMPOSING:
+- 	    /* nfa_regmatch() will match all the bytes of this composing char. */
+- 	    break;
+- #endif
+- 
+  	case NFA_SKIP_CHAR:
+  	case NFA_NOPEN:
+  	case NFA_NCLOSE:
+! 	    addstate(l, state->out, sub, off);
+  	    break;
+  
+! 	case NFA_MOPEN + 0:
+! 	case NFA_MOPEN + 1:
+! 	case NFA_MOPEN + 2:
+! 	case NFA_MOPEN + 3:
+! 	case NFA_MOPEN + 4:
+! 	case NFA_MOPEN + 5:
+! 	case NFA_MOPEN + 6:
+! 	case NFA_MOPEN + 7:
+! 	case NFA_MOPEN + 8:
+! 	case NFA_MOPEN + 9:
+  	case NFA_ZSTART:
+  	    if (state->c == NFA_ZSTART)
+  		subidx = 0;
+  	    else
+  		subidx = state->c - NFA_MOPEN;
+  
+  	    /* Set the position (with "off") in the subexpression.  Save and
+  	     * restore it when it was in use.  Otherwise fill any gap. */
+--- 3166,3222 ----
+  	    break;
+  
+  	case NFA_SPLIT:
+! 	    /* order matters here */
+! 	    addstate(l, state->out, subs, off);
+! 	    addstate(l, state->out1, subs, off);
+  	    break;
+  
+  	case NFA_SKIP_CHAR:
+  	case NFA_NOPEN:
+  	case NFA_NCLOSE:
+! 	    addstate(l, state->out, subs, off);
+  	    break;
+  
+! 	case NFA_MOPEN:
+! 	case NFA_MOPEN1:
+! 	case NFA_MOPEN2:
+! 	case NFA_MOPEN3:
+! 	case NFA_MOPEN4:
+! 	case NFA_MOPEN5:
+! 	case NFA_MOPEN6:
+! 	case NFA_MOPEN7:
+! 	case NFA_MOPEN8:
+! 	case NFA_MOPEN9:
+! #ifdef FEAT_SYN_HL
+! 	case NFA_ZOPEN:
+! 	case NFA_ZOPEN1:
+! 	case NFA_ZOPEN2:
+! 	case NFA_ZOPEN3:
+! 	case NFA_ZOPEN4:
+! 	case NFA_ZOPEN5:
+! 	case NFA_ZOPEN6:
+! 	case NFA_ZOPEN7:
+! 	case NFA_ZOPEN8:
+! 	case NFA_ZOPEN9:
+! #endif
+  	case NFA_ZSTART:
+  	    if (state->c == NFA_ZSTART)
++ 	    {
+  		subidx = 0;
++ 		sub = &subs->norm;
++ 	    }
++ #ifdef FEAT_SYN_HL
++ 	    else if (state->c >= NFA_ZOPEN)
++ 	    {
++ 		subidx = state->c - NFA_ZOPEN;
++ 		sub = &subs->synt;
++ 	    }
++ #endif
+  	    else
++ 	    {
+  		subidx = state->c - NFA_MOPEN;
++ 		sub = &subs->norm;
++ 	    }
+  
+  	    /* Set the position (with "off") in the subexpression.  Save and
+  	     * restore it when it was in use.  Otherwise fill any gap. */
+***************
+*** 3007,3013 ****
+  		sub->list.line[subidx].start = reginput + off;
+  	    }
+  
+! 	    addstate(l, state->out, sub, off);
+  
+  	    if (save_in_use == -1)
+  	    {
+--- 3270,3276 ----
+  		sub->list.line[subidx].start = reginput + off;
+  	    }
+  
+! 	    addstate(l, state->out, subs, off);
+  
+  	    if (save_in_use == -1)
+  	    {
+***************
+*** 3020,3047 ****
+  		sub->in_use = save_in_use;
+  	    break;
+  
+! 	case NFA_MCLOSE + 0:
+  	    if (nfa_has_zend)
+  	    {
+  		/* Do not overwrite the position set by \ze. If no \ze
+  		 * encountered end will be set in nfa_regtry(). */
+! 		addstate(l, state->out, sub, off);
+  		break;
+  	    }
+! 	case NFA_MCLOSE + 1:
+! 	case NFA_MCLOSE + 2:
+! 	case NFA_MCLOSE + 3:
+! 	case NFA_MCLOSE + 4:
+! 	case NFA_MCLOSE + 5:
+! 	case NFA_MCLOSE + 6:
+! 	case NFA_MCLOSE + 7:
+! 	case NFA_MCLOSE + 8:
+! 	case NFA_MCLOSE + 9:
+  	case NFA_ZEND:
+  	    if (state->c == NFA_ZEND)
+  		subidx = 0;
+  	    else
+  		subidx = state->c - NFA_MCLOSE;
+  
+  	    /* We don't fill in gaps here, there must have been an MOPEN that
+  	     * has done that. */
+--- 3283,3335 ----
+  		sub->in_use = save_in_use;
+  	    break;
+  
+! 	case NFA_MCLOSE:
+  	    if (nfa_has_zend)
+  	    {
+  		/* Do not overwrite the position set by \ze. If no \ze
+  		 * encountered end will be set in nfa_regtry(). */
+! 		addstate(l, state->out, subs, off);
+  		break;
+  	    }
+! 	case NFA_MCLOSE1:
+! 	case NFA_MCLOSE2:
+! 	case NFA_MCLOSE3:
+! 	case NFA_MCLOSE4:
+! 	case NFA_MCLOSE5:
+! 	case NFA_MCLOSE6:
+! 	case NFA_MCLOSE7:
+! 	case NFA_MCLOSE8:
+! 	case NFA_MCLOSE9:
+! #ifdef FEAT_SYN_HL
+! 	case NFA_ZCLOSE:
+! 	case NFA_ZCLOSE1:
+! 	case NFA_ZCLOSE2:
+! 	case NFA_ZCLOSE3:
+! 	case NFA_ZCLOSE4:
+! 	case NFA_ZCLOSE5:
+! 	case NFA_ZCLOSE6:
+! 	case NFA_ZCLOSE7:
+! 	case NFA_ZCLOSE8:
+! 	case NFA_ZCLOSE9:
+! #endif
+  	case NFA_ZEND:
+  	    if (state->c == NFA_ZEND)
++ 	    {
+  		subidx = 0;
++ 		sub = &subs->norm;
++ 	    }
++ #ifdef FEAT_SYN_HL
++ 	    else if (state->c >= NFA_ZCLOSE)
++ 	    {
++ 		subidx = state->c - NFA_ZCLOSE;
++ 		sub = &subs->synt;
++ 	    }
++ #endif
+  	    else
++ 	    {
+  		subidx = state->c - NFA_MCLOSE;
++ 		sub = &subs->norm;
++ 	    }
+  
+  	    /* We don't fill in gaps here, there must have been an MOPEN that
+  	     * has done that. */
+***************
+*** 3069,3075 ****
+  		sub->list.line[subidx].end = reginput + off;
+  	    }
+  
+! 	    addstate(l, state->out, sub, off);
+  
+  	    if (REG_MULTI)
+  		sub->list.multi[subidx].end = save_lpos;
+--- 3357,3363 ----
+  		sub->list.line[subidx].end = reginput + off;
+  	    }
+  
+! 	    addstate(l, state->out, subs, off);
+  
+  	    if (REG_MULTI)
+  		sub->list.multi[subidx].end = save_lpos;
+***************
+*** 3087,3096 ****
+   * matters for alternatives.
+   */
+      static void
+! addstate_here(l, state, sub, ip)
+      nfa_list_T		*l;	/* runtime state list */
+      nfa_state_T		*state;	/* state to update */
+!     regsub_T		*sub;	/* pointers to subexpressions */
+      int			*ip;
+  {
+      int tlen = l->n;
+--- 3375,3384 ----
+   * matters for alternatives.
+   */
+      static void
+! addstate_here(l, state, subs, ip)
+      nfa_list_T		*l;	/* runtime state list */
+      nfa_state_T		*state;	/* state to update */
+!     regsubs_T		*subs;	/* pointers to subexpressions */
+      int			*ip;
+  {
+      int tlen = l->n;
+***************
+*** 3098,3104 ****
+      int i = *ip;
+  
+      /* first add the state(s) at the end, so that we know how many there are */
+!     addstate(l, state, sub, 0);
+  
+      /* when "*ip" was at the end of the list, nothing to do */
+      if (i + 1 == tlen)
+--- 3386,3392 ----
+      int i = *ip;
+  
+      /* first add the state(s) at the end, so that we know how many there are */
+!     addstate(l, state, subs, 0);
+  
+      /* when "*ip" was at the end of the list, nothing to do */
+      if (i + 1 == tlen)
+***************
+*** 3212,3218 ****
+  
+  /*
+   * Check for a match with subexpression "subidx".
+!  * return TRUE if it matches.
+   */
+      static int
+  match_backref(sub, subidx, bytelen)
+--- 3500,3506 ----
+  
+  /*
+   * Check for a match with subexpression "subidx".
+!  * Return TRUE if it matches.
+   */
+      static int
+  match_backref(sub, subidx, bytelen)
+***************
+*** 3260,3265 ****
+--- 3548,3586 ----
+      return FALSE;
+  }
+  
++ #ifdef FEAT_SYN_HL
++ 
++ static int match_zref __ARGS((int subidx, int *bytelen));
++ 
++ /*
++  * Check for a match with \z subexpression "subidx".
++  * Return TRUE if it matches.
++  */
++     static int
++ match_zref(subidx, bytelen)
++     int		subidx;
++     int		*bytelen;   /* out: length of match in bytes */
++ {
++     int		len;
++ 
++     cleanup_zsubexpr();
++     if (re_extmatch_in == NULL || re_extmatch_in->matches[subidx] == NULL)
++     {
++ 	/* backref was not set, match an empty string */
++ 	*bytelen = 0;
++ 	return TRUE;
++     }
++ 
++     len = (int)STRLEN(re_extmatch_in->matches[subidx]);
++     if (cstrncmp(re_extmatch_in->matches[subidx], reginput, &len) == 0)
++     {
++ 	*bytelen = len;
++ 	return TRUE;
++     }
++     return FALSE;
++ }
++ #endif
++ 
+  /*
+   * Set all NFA nodes' list ID equal to -1.
+   */
+***************
+*** 3334,3340 ****
+      return val == pos;
+  }
+  
+! static int nfa_regmatch __ARGS((nfa_state_T *start, regsub_T *submatch, regsub_T *m, save_se_T *endp));
+  
+  /*
+   * Main matching routine.
+--- 3655,3661 ----
+      return val == pos;
+  }
+  
+! static int nfa_regmatch __ARGS((nfa_state_T *start, regsubs_T *submatch, regsubs_T *m, save_se_T *endp));
+  
+  /*
+   * Main matching routine.
+***************
+*** 3349,3356 ****
+      static int
+  nfa_regmatch(start, submatch, m, endp)
+      nfa_state_T		*start;
+!     regsub_T		*submatch;
+!     regsub_T		*m;
+      save_se_T		*endp;
+  {
+      int		result;
+--- 3670,3677 ----
+      static int
+  nfa_regmatch(start, submatch, m, endp)
+      nfa_state_T		*start;
+!     regsubs_T		*submatch;
+!     regsubs_T		*m;
+      save_se_T		*endp;
+  {
+      int		result;
+***************
+*** 3429,3435 ****
+  #define	ADD_POS_NEG_STATE(node)						    \
+      ll = listtbl[result ? 1 : 0][node->negated];			    \
+      if (ll != NULL)							    \
+! 	addstate(ll, node->out , &t->sub, clen);
+  
+  
+      /*
+--- 3750,3756 ----
+  #define	ADD_POS_NEG_STATE(node)						    \
+      ll = listtbl[result ? 1 : 0][node->negated];			    \
+      if (ll != NULL)							    \
+! 	addstate(ll, node->out , &t->subs, clen);
+  
+  
+      /*
+***************
+*** 3531,3556 ****
+  	    {
+  	    case NFA_MATCH:
+  	      {
+- 		int j;
+- 
+  		nfa_match = TRUE;
+! 		submatch->in_use = t->sub.in_use;
+! 		if (REG_MULTI)
+! 		    for (j = 0; j < submatch->in_use; j++)
+! 		    {
+! 			submatch->list.multi[j].start =
+! 						   t->sub.list.multi[j].start;
+! 			submatch->list.multi[j].end = t->sub.list.multi[j].end;
+! 		    }
+! 		else
+! 		    for (j = 0; j < submatch->in_use; j++)
+! 		    {
+! 			submatch->list.line[j].start =
+! 						    t->sub.list.line[j].start;
+! 			submatch->list.line[j].end = t->sub.list.line[j].end;
+! 		    }
+  #ifdef ENABLE_LOG
+! 		log_subexpr(&t->sub);
+  #endif
+  		/* Found the left-most longest match, do not look at any other
+  		 * states at this position.  When the list of states is going
+--- 3852,3864 ----
+  	    {
+  	    case NFA_MATCH:
+  	      {
+  		nfa_match = TRUE;
+! 		copy_sub(&submatch->norm, &t->subs.norm);
+! #ifdef FEAT_SYN_HL
+! 		copy_sub(&submatch->synt, &t->subs.synt);
+! #endif
+  #ifdef ENABLE_LOG
+! 		log_subsexpr(&t->subs);
+  #endif
+  		/* Found the left-most longest match, do not look at any other
+  		 * states at this position.  When the list of states is going
+***************
+*** 3570,3578 ****
+  		 * finished successfully, so return control to the parent
+  		 * nfa_regmatch().  Submatches are stored in *m, and used in
+  		 * the parent call. */
+! 		if (start->c == NFA_MOPEN + 0)
+  		    /* TODO: do we ever get here? */
+! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
+  		else
+  		{
+  #ifdef ENABLE_LOG
+--- 3878,3886 ----
+  		 * finished successfully, so return control to the parent
+  		 * nfa_regmatch().  Submatches are stored in *m, and used in
+  		 * the parent call. */
+! 		if (start->c == NFA_MOPEN)
+  		    /* TODO: do we ever get here? */
+! 		    addstate_here(thislist, t->state->out, &t->subs, &listidx);
+  		else
+  		{
+  #ifdef ENABLE_LOG
+***************
+*** 3600,3607 ****
+  
+  		    /* do not set submatches for \@! */
+  		    if (!t->state->negated)
+! 			/* TODO: only copy positions in use. */
+! 			*m = t->sub;
+  		    nfa_match = TRUE;
+  		}
+  		break;
+--- 3908,3919 ----
+  
+  		    /* do not set submatches for \@! */
+  		    if (!t->state->negated)
+! 		    {
+! 			copy_sub(&m->norm, &t->subs.norm);
+! #ifdef FEAT_SYN_HL
+! 			copy_sub(&m->synt, &t->subs.synt);
+! #endif
+! 		    }
+  		    nfa_match = TRUE;
+  		}
+  		break;
+***************
+*** 3630,3636 ****
+  
+  		    /* Go back the specified number of bytes, or as far as the
+  		     * start of the previous line, to try matching "\@<=" or
+! 		     * not matching "\@<!". */
+  		    if (t->state->val <= 0)
+  		    {
+  			if (REG_MULTI)
+--- 3942,3950 ----
+  
+  		    /* Go back the specified number of bytes, or as far as the
+  		     * start of the previous line, to try matching "\@<=" or
+! 		     * not matching "\@<!".
+! 		     * TODO: This is very inefficient! Would be better to
+! 		     * first check for a match with what follows. */
+  		    if (t->state->val <= 0)
+  		    {
+  			if (REG_MULTI)
+***************
+*** 3722,3748 ****
+  		/* for \@! it is a match when result is FALSE */
+  		if (result != t->state->negated)
+  		{
+- 		    int j;
+- 
+  		    /* Copy submatch info from the recursive call */
+! 		    if (REG_MULTI)
+! 			for (j = 1; j < m->in_use; j++)
+! 			{
+! 			    t->sub.list.multi[j].start = m->list.multi[j].start;
+! 			    t->sub.list.multi[j].end = m->list.multi[j].end;
+! 			}
+! 		    else
+! 			for (j = 1; j < m->in_use; j++)
+! 			{
+! 			    t->sub.list.line[j].start = m->list.line[j].start;
+! 			    t->sub.list.line[j].end = m->list.line[j].end;
+! 			}
+! 		    if (m->in_use > t->sub.in_use)
+! 			t->sub.in_use = m->in_use;
+  
+  		    /* t->state->out1 is the corresponding END_INVISIBLE node;
+  		     * Add it to the current list (zero-width match). */
+! 		    addstate_here(thislist, t->state->out1->out, &t->sub,
+  								    &listidx);
+  		}
+  		break;
+--- 4036,4050 ----
+  		/* for \@! it is a match when result is FALSE */
+  		if (result != t->state->negated)
+  		{
+  		    /* Copy submatch info from the recursive call */
+! 		    copy_sub_off(&t->subs.norm, &m->norm);
+! #ifdef FEAT_SYN_HL
+! 		    copy_sub_off(&t->subs.synt, &m->synt);
+! #endif
+  
+  		    /* t->state->out1 is the corresponding END_INVISIBLE node;
+  		     * Add it to the current list (zero-width match). */
+! 		    addstate_here(thislist, t->state->out1->out, &t->subs,
+  								    &listidx);
+  		}
+  		break;
+***************
+*** 3750,3761 ****
+  
+  	    case NFA_BOL:
+  		if (reginput == regline)
+! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
+  		break;
+  
+  	    case NFA_EOL:
+  		if (curc == NUL)
+! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
+  		break;
+  
+  	    case NFA_BOW:
+--- 4052,4063 ----
+  
+  	    case NFA_BOL:
+  		if (reginput == regline)
+! 		    addstate_here(thislist, t->state->out, &t->subs, &listidx);
+  		break;
+  
+  	    case NFA_EOL:
+  		if (curc == NUL)
+! 		    addstate_here(thislist, t->state->out, &t->subs, &listidx);
+  		break;
+  
+  	    case NFA_BOW:
+***************
+*** 3782,3788 ****
+  				   && vim_iswordc_buf(reginput[-1], reg_buf)))
+  		    bow = FALSE;
+  		if (bow)
+! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
+  		break;
+  	    }
+  
+--- 4084,4090 ----
+  				   && vim_iswordc_buf(reginput[-1], reg_buf)))
+  		    bow = FALSE;
+  		if (bow)
+! 		    addstate_here(thislist, t->state->out, &t->subs, &listidx);
+  		break;
+  	    }
+  
+***************
+*** 3810,3828 ****
+  					   && vim_iswordc_buf(curc, reg_buf)))
+  		    eow = FALSE;
+  		if (eow)
+! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
+  		break;
+  	    }
+  
+  	    case NFA_BOF:
+  		if (reglnum == 0 && reginput == regline
+  					&& (!REG_MULTI || reg_firstlnum == 1))
+! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
+  		break;
+  
+  	    case NFA_EOF:
+  		if (reglnum == reg_maxline && curc == NUL)
+! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
+  		break;
+  
+  #ifdef FEAT_MBYTE
+--- 4112,4130 ----
+  					   && vim_iswordc_buf(curc, reg_buf)))
+  		    eow = FALSE;
+  		if (eow)
+! 		    addstate_here(thislist, t->state->out, &t->subs, &listidx);
+  		break;
+  	    }
+  
+  	    case NFA_BOF:
+  		if (reglnum == 0 && reginput == regline
+  					&& (!REG_MULTI || reg_firstlnum == 1))
+! 		    addstate_here(thislist, t->state->out, &t->subs, &listidx);
+  		break;
+  
+  	    case NFA_EOF:
+  		if (reglnum == reg_maxline && curc == NUL)
+! 		    addstate_here(thislist, t->state->out, &t->subs, &listidx);
+  		break;
+  
+  #ifdef FEAT_MBYTE
+***************
+*** 3911,3922 ****
+  		    go_to_nextline = TRUE;
+  		    /* Pass -1 for the offset, which means taking the position
+  		     * at the start of the next line. */
+! 		    addstate(nextlist, t->state->out, &t->sub, -1);
+  		}
+  		else if (curc == '\n' && reg_line_lbr)
+  		{
+  		    /* match \n as if it is an ordinary character */
+! 		    addstate(nextlist, t->state->out, &t->sub, 1);
+  		}
+  		break;
+  
+--- 4213,4224 ----
+  		    go_to_nextline = TRUE;
+  		    /* Pass -1 for the offset, which means taking the position
+  		     * at the start of the next line. */
+! 		    addstate(nextlist, t->state->out, &t->subs, -1);
+  		}
+  		else if (curc == '\n' && reg_line_lbr)
+  		{
+  		    /* match \n as if it is an ordinary character */
+! 		    addstate(nextlist, t->state->out, &t->subs, 1);
+  		}
+  		break;
+  
+***************
+*** 3944,3956 ****
+  		/* This follows a series of negated nodes, like:
+  		 * CHAR(x), NFA_NOT, CHAR(y), NFA_NOT etc. */
+  		if (curc > 0)
+! 		    addstate(nextlist, t->state->out, &t->sub, clen);
+  		break;
+  
+  	    case NFA_ANY:
+  		/* Any char except '\0', (end of input) does not match. */
+  		if (curc > 0)
+! 		    addstate(nextlist, t->state->out, &t->sub, clen);
+  		break;
+  
+  	    /*
+--- 4246,4258 ----
+  		/* This follows a series of negated nodes, like:
+  		 * CHAR(x), NFA_NOT, CHAR(y), NFA_NOT etc. */
+  		if (curc > 0)
+! 		    addstate(nextlist, t->state->out, &t->subs, clen);
+  		break;
+  
+  	    case NFA_ANY:
+  		/* Any char except '\0', (end of input) does not match. */
+  		if (curc > 0)
+! 		    addstate(nextlist, t->state->out, &t->subs, clen);
+  		break;
+  
+  	    /*
+***************
+*** 4096,4114 ****
+  	    case NFA_BACKREF7:
+  	    case NFA_BACKREF8:
+  	    case NFA_BACKREF9:
+! 		/* \1 .. \9 */
+  	      {
+! 		int subidx = t->state->c - NFA_BACKREF1 + 1;
+  		int bytelen;
+  
+! 		result = match_backref(&t->sub, subidx, &bytelen);
+  		if (result)
+  		{
+  		    if (bytelen == 0)
+  		    {
+  			/* empty match always works, add NFA_SKIP with zero to
+  			 * be used next */
+! 			addstate_here(thislist, t->state->out, &t->sub,
+  								    &listidx);
+  			thislist->t[listidx + 1].count = 0;
+  		    }
+--- 4398,4439 ----
+  	    case NFA_BACKREF7:
+  	    case NFA_BACKREF8:
+  	    case NFA_BACKREF9:
+! #ifdef FEAT_SYN_HL
+! 	    case NFA_ZREF1:
+! 	    case NFA_ZREF2:
+! 	    case NFA_ZREF3:
+! 	    case NFA_ZREF4:
+! 	    case NFA_ZREF5:
+! 	    case NFA_ZREF6:
+! 	    case NFA_ZREF7:
+! 	    case NFA_ZREF8:
+! 	    case NFA_ZREF9:
+! #endif
+! 		/* \1 .. \9  \z1 .. \z9 */
+  	      {
+! 		int subidx;
+  		int bytelen;
+  
+! 		if (t->state->c <= NFA_BACKREF9)
+! 		{
+! 		    subidx = t->state->c - NFA_BACKREF1 + 1;
+! 		    result = match_backref(&t->subs.norm, subidx, &bytelen);
+! 		}
+! #ifdef FEAT_SYN_HL
+! 		else
+! 		{
+! 		    subidx = t->state->c - NFA_ZREF1 + 1;
+! 		    result = match_zref(subidx, &bytelen);
+! 		}
+! #endif
+! 
+  		if (result)
+  		{
+  		    if (bytelen == 0)
+  		    {
+  			/* empty match always works, add NFA_SKIP with zero to
+  			 * be used next */
+! 			addstate_here(thislist, t->state->out, &t->subs,
+  								    &listidx);
+  			thislist->t[listidx + 1].count = 0;
+  		    }
+***************
+*** 4116,4134 ****
+  		    {
+  			/* match current character, jump ahead to out of
+  			 * NFA_SKIP */
+! 			addstate(nextlist, t->state->out->out, &t->sub, clen);
+  #ifdef ENABLE_LOG
+! 			log_subexpr(&nextlist->t[nextlist->n - 1].sub);
+  #endif
+  		    }
+  		    else
+  		    {
+  			/* skip ofer the matched characters, set character
+  			 * count in NFA_SKIP */
+! 			addstate(nextlist, t->state->out, &t->sub, bytelen);
+  			nextlist->t[nextlist->n - 1].count = bytelen - clen;
+  #ifdef ENABLE_LOG
+! 			log_subexpr(&nextlist->t[nextlist->n - 1].sub);
+  #endif
+  		    }
+  
+--- 4441,4459 ----
+  		    {
+  			/* match current character, jump ahead to out of
+  			 * NFA_SKIP */
+! 			addstate(nextlist, t->state->out->out, &t->subs, clen);
+  #ifdef ENABLE_LOG
+! 			log_subsexpr(&nextlist->t[nextlist->n - 1].subs);
+  #endif
+  		    }
+  		    else
+  		    {
+  			/* skip ofer the matched characters, set character
+  			 * count in NFA_SKIP */
+! 			addstate(nextlist, t->state->out, &t->subs, bytelen);
+  			nextlist->t[nextlist->n - 1].count = bytelen - clen;
+  #ifdef ENABLE_LOG
+! 			log_subsexpr(&nextlist->t[nextlist->n - 1].subs);
+  #endif
+  		    }
+  
+***************
+*** 4140,4157 ****
+  	      if (t->count - clen <= 0)
+  	      {
+  		  /* end of match, go to what follows */
+! 		  addstate(nextlist, t->state->out, &t->sub, clen);
+  #ifdef ENABLE_LOG
+! 		  log_subexpr(&nextlist->t[nextlist->n - 1].sub);
+  #endif
+  	      }
+  	      else
+  	      {
+  		  /* add state again with decremented count */
+! 		  addstate(nextlist, t->state, &t->sub, 0);
+  		  nextlist->t[nextlist->n - 1].count = t->count - clen;
+  #ifdef ENABLE_LOG
+! 		  log_subexpr(&nextlist->t[nextlist->n - 1].sub);
+  #endif
+  	      }
+  	      break;
+--- 4465,4482 ----
+  	      if (t->count - clen <= 0)
+  	      {
+  		  /* end of match, go to what follows */
+! 		  addstate(nextlist, t->state->out, &t->subs, clen);
+  #ifdef ENABLE_LOG
+! 		  log_subsexpr(&nextlist->t[nextlist->n - 1].subs);
+  #endif
+  	      }
+  	      else
+  	      {
+  		  /* add state again with decremented count */
+! 		  addstate(nextlist, t->state, &t->subs, 0);
+  		  nextlist->t[nextlist->n - 1].count = t->count - clen;
+  #ifdef ENABLE_LOG
+! 		  log_subsexpr(&nextlist->t[nextlist->n - 1].subs);
+  #endif
+  	      }
+  	      break;
+***************
+*** 4169,4175 ****
+  			nfa_re_num_cmp(t->state->val, t->state->c - NFA_LNUM,
+  			    (long_u)(reglnum + reg_firstlnum)));
+  		if (result)
+! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
+  		break;
+  
+  	    case NFA_COL:
+--- 4494,4500 ----
+  			nfa_re_num_cmp(t->state->val, t->state->c - NFA_LNUM,
+  			    (long_u)(reglnum + reg_firstlnum)));
+  		if (result)
+! 		    addstate_here(thislist, t->state->out, &t->subs, &listidx);
+  		break;
+  
+  	    case NFA_COL:
+***************
+*** 4178,4184 ****
+  		result = nfa_re_num_cmp(t->state->val, t->state->c - NFA_COL,
+  			(long_u)(reginput - regline) + 1);
+  		if (result)
+! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
+  		break;
+  
+  	    case NFA_VCOL:
+--- 4503,4509 ----
+  		result = nfa_re_num_cmp(t->state->val, t->state->c - NFA_COL,
+  			(long_u)(reginput - regline) + 1);
+  		if (result)
+! 		    addstate_here(thislist, t->state->out, &t->subs, &listidx);
+  		break;
+  
+  	    case NFA_VCOL:
+***************
+*** 4189,4195 ****
+  			    reg_win == NULL ? curwin : reg_win,
+  			    regline, (colnr_T)(reginput - regline)) + 1);
+  		if (result)
+! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
+  		break;
+  
+  	    case NFA_CURSOR:
+--- 4514,4520 ----
+  			    reg_win == NULL ? curwin : reg_win,
+  			    regline, (colnr_T)(reginput - regline)) + 1);
+  		if (result)
+! 		    addstate_here(thislist, t->state->out, &t->subs, &listidx);
+  		break;
+  
+  	    case NFA_CURSOR:
+***************
+*** 4198,4204 ****
+  			&& ((colnr_T)(reginput - regline)
+  						   == reg_win->w_cursor.col));
+  		if (result)
+! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
+  		break;
+  
+  	    default:	/* regular character */
+--- 4523,4529 ----
+  			&& ((colnr_T)(reginput - regline)
+  						   == reg_win->w_cursor.col));
+  		if (result)
+! 		    addstate_here(thislist, t->state->out, &t->subs, &listidx);
+  		break;
+  
+  	    default:	/* regular character */
+***************
+*** 4238,4244 ****
+  	 * Unless "endp" is not NULL, then we match the end position.
+  	 * Also don't start a match past the first line. */
+  	if (nfa_match == FALSE
+! 		&& ((start->c == NFA_MOPEN + 0
+  			&& reglnum == 0
+  			&& clen != 0
+  			&& (ireg_maxcol == 0
+--- 4563,4569 ----
+  	 * Unless "endp" is not NULL, then we match the end position.
+  	 * Also don't start a match past the first line. */
+  	if (nfa_match == FALSE
+! 		&& ((start->c == NFA_MOPEN
+  			&& reglnum == 0
+  			&& clen != 0
+  			&& (ireg_maxcol == 0
+***************
+*** 4305,4322 ****
+   * Returns 0 for failure, number of lines contained in the match otherwise.
+   */
+      static long
+! nfa_regtry(start, col)
+!     nfa_state_T	*start;
+!     colnr_T	col;
+  {
+      int		i;
+!     regsub_T	sub, m;
+  #ifdef ENABLE_LOG
+      FILE	*f;
+  #endif
+  
+      reginput = regline + col;
+      need_clear_subexpr = TRUE;
+  
+  #ifdef ENABLE_LOG
+      f = fopen(NFA_REGEXP_RUN_LOG, "a");
+--- 4630,4653 ----
+   * Returns 0 for failure, number of lines contained in the match otherwise.
+   */
+      static long
+! nfa_regtry(prog, col)
+!     nfa_regprog_T   *prog;
+!     colnr_T	    col;
+  {
+      int		i;
+!     regsubs_T	subs, m;
+!     nfa_state_T	*start = prog->start;
+  #ifdef ENABLE_LOG
+      FILE	*f;
+  #endif
+  
+      reginput = regline + col;
+      need_clear_subexpr = TRUE;
++ #ifdef FEAT_SYN_HL
++     /* Clear the external match subpointers if necessary. */
++     if (prog->reghasz == REX_SET)
++ 	need_clear_zsubexpr = TRUE;
++ #endif
+  
+  #ifdef ENABLE_LOG
+      f = fopen(NFA_REGEXP_RUN_LOG, "a");
+***************
+*** 4337,4366 ****
+  	EMSG(_("Could not open temporary log file for writing "));
+  #endif
+  
+!     if (REG_MULTI)
+!     {
+! 	/* Use 0xff to set lnum to -1 */
+! 	vim_memset(sub.list.multi, 0xff, sizeof(struct multipos) * nfa_nsubexpr);
+! 	vim_memset(m.list.multi, 0xff, sizeof(struct multipos) * nfa_nsubexpr);
+!     }
+!     else
+!     {
+! 	vim_memset(sub.list.line, 0, sizeof(struct linepos) * nfa_nsubexpr);
+! 	vim_memset(m.list.line, 0, sizeof(struct linepos) * nfa_nsubexpr);
+!     }
+!     sub.in_use = 0;
+!     m.in_use = 0;
+  
+!     if (nfa_regmatch(start, &sub, &m, NULL) == FALSE)
+  	return 0;
+  
+      cleanup_subexpr();
+      if (REG_MULTI)
+      {
+! 	for (i = 0; i < sub.in_use; i++)
+  	{
+! 	    reg_startpos[i] = sub.list.multi[i].start;
+! 	    reg_endpos[i] = sub.list.multi[i].end;
+  	}
+  
+  	if (reg_startpos[0].lnum < 0)
+--- 4668,4690 ----
+  	EMSG(_("Could not open temporary log file for writing "));
+  #endif
+  
+!     clear_sub(&subs.norm);
+!     clear_sub(&m.norm);
+! #ifdef FEAT_SYN_HL
+!     clear_sub(&subs.synt);
+!     clear_sub(&m.synt);
+! #endif
+  
+!     if (nfa_regmatch(start, &subs, &m, NULL) == FALSE)
+  	return 0;
+  
+      cleanup_subexpr();
+      if (REG_MULTI)
+      {
+! 	for (i = 0; i < subs.norm.in_use; i++)
+  	{
+! 	    reg_startpos[i] = subs.norm.list.multi[i].start;
+! 	    reg_endpos[i] = subs.norm.list.multi[i].end;
+  	}
+  
+  	if (reg_startpos[0].lnum < 0)
+***************
+*** 4380,4389 ****
+      }
+      else
+      {
+! 	for (i = 0; i < sub.in_use; i++)
+  	{
+! 	    reg_startp[i] = sub.list.line[i].start;
+! 	    reg_endp[i] = sub.list.line[i].end;
+  	}
+  
+  	if (reg_startp[0] == NULL)
+--- 4704,4713 ----
+      }
+      else
+      {
+! 	for (i = 0; i < subs.norm.in_use; i++)
+  	{
+! 	    reg_startp[i] = subs.norm.list.line[i].start;
+! 	    reg_endp[i] = subs.norm.list.line[i].end;
+  	}
+  
+  	if (reg_startp[0] == NULL)
+***************
+*** 4392,4397 ****
+--- 4716,4758 ----
+  	    reg_endp[0] = reginput;
+      }
+  
++ #ifdef FEAT_SYN_HL
++     /* Package any found \z(...\) matches for export. Default is none. */
++     unref_extmatch(re_extmatch_out);
++     re_extmatch_out = NULL;
++ 
++     if (prog->reghasz == REX_SET)
++     {
++ 	int		i;
++ 
++ 	cleanup_zsubexpr();
++ 	re_extmatch_out = make_extmatch();
++ 	for (i = 0; i < subs.synt.in_use; i++)
++ 	{
++ 	    if (REG_MULTI)
++ 	    {
++ 		struct multipos *mpos = &subs.synt.list.multi[i];
++ 
++ 		/* Only accept single line matches. */
++ 		if (mpos->start.lnum >= 0 && mpos->start.lnum == mpos->end.lnum)
++ 		    re_extmatch_out->matches[i] =
++ 			vim_strnsave(reg_getline(mpos->start.lnum)
++ 							    + mpos->start.col,
++ 					     mpos->end.col - mpos->start.col);
++ 	    }
++ 	    else
++ 	    {
++ 		struct linepos *lpos = &subs.synt.list.line[i];
++ 
++ 		if (lpos->start != NULL && lpos->end != NULL)
++ 		    re_extmatch_out->matches[i] =
++ 			    vim_strnsave(lpos->start,
++ 					      (int)(lpos->end - lpos->start));
++ 	    }
++ 	}
++     }
++ #endif
++ 
+      return 1 + reglnum;
+  }
+  
+***************
+*** 4461,4467 ****
+  	prog->state[i].lastlist = 0;
+      }
+  
+!     retval = nfa_regtry(prog->start, col);
+  
+  theend:
+      return retval;
+--- 4822,4828 ----
+  	prog->state[i].lastlist = 0;
+      }
+  
+!     retval = nfa_regtry(prog, col);
+  
+  theend:
+      return retval;
+***************
+*** 4552,4557 ****
+--- 4913,4922 ----
+      nfa_postfix_dump(expr, OK);
+      nfa_dump(prog);
+  #endif
++ #ifdef FEAT_SYN_HL
++     /* Remember whether this pattern has any \z specials in it. */
++     prog->reghasz = re_has_z;
++ #endif
+  
+  out:
+      vim_free(post_start);
+*** ../vim-7.3.1089/src/version.c	2013-06-01 20:32:09.000000000 +0200
+--- src/version.c	2013-06-01 22:29:51.000000000 +0200
+***************
+*** 730,731 ****
+--- 730,733 ----
+  {   /* Add new patch number below this line */
++ /**/
++     1090,
+  /**/
+
+-- 
+Despite the cost of living, have you noticed how it remains so popular?
+
+ /// Bram Moolenaar -- Bram at Moolenaar.net -- 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    ///


More information about the scm-commits mailing list