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 -- [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/groups/opt_out.


Raspunde prin e-mail lui