Loading ...
Sorry, an error occurred while loading the content.

70480Patch 7.3.10

Expand Messages
  • Bram Moolenaar
    Jun 1, 2013
    • 0 Attachment
      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@... -- 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 vim_dev+unsubscribe@....
      For more options, visit https://groups.google.com/groups/opt_out.
    • Show all 8 messages in this topic