diff --git a/7.3.1090 b/7.3.1090 new file mode 100644 index 0000000..1278fae --- /dev/null +++ b/7.3.1090 @@ -0,0 +1,1893 @@ +To: vim_dev@googlegroups.com +Subject: Patch 7.3.10 +Fcc: outbox +From: Bram Moolenaar +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +Patch 7.3.1090 +Problem: New regexp engine does not support \z1 .. \z9 and \z(. +Solution: Implement the syntax submatches. +Files: src/regexp.h, src/regexp_nfa.c + + +*** ../vim-7.3.1089/src/regexp.h 2013-05-30 17:05:34.000000000 +0200 +--- src/regexp.h 2013-06-01 22:18:07.000000000 +0200 +*************** +*** 55,61 **** +--- 55,63 ---- + char_u reganch; + char_u *regmust; + int regmlen; ++ #ifdef FEAT_SYN_HL + char_u reghasz; ++ #endif + char_u program[1]; /* actually longer.. */ + } bt_regprog_T; + +*************** +*** 88,93 **** +--- 90,98 ---- + nfa_state_T *start; + int has_zend; /* pattern contains \ze */ + int has_backref; /* pattern contains \1 .. \9 */ ++ #ifdef FEAT_SYN_HL ++ int reghasz; ++ #endif + int nsubexp; /* number of () */ + int nstate; + nfa_state_T state[0]; /* actually longer.. */ +*** ../vim-7.3.1089/src/regexp_nfa.c 2013-06-01 19:54:39.000000000 +0200 +--- src/regexp_nfa.c 2013-06-01 22:54:08.000000000 +0200 +*************** +*** 78,90 **** + NFA_BACKREF7, /* \7 */ + NFA_BACKREF8, /* \8 */ + NFA_BACKREF9, /* \9 */ + NFA_SKIP, /* Skip characters */ + + NFA_MOPEN, +! NFA_MCLOSE = NFA_MOPEN + NSUBEXP, + + /* NFA_FIRST_NL */ +! NFA_ANY = NFA_MCLOSE + NSUBEXP, /* Match any one character. */ + NFA_ANYOF, /* Match any character in this string. */ + NFA_ANYBUT, /* Match any character not in this string. */ + NFA_IDENT, /* Match identifier char */ +--- 78,144 ---- + NFA_BACKREF7, /* \7 */ + NFA_BACKREF8, /* \8 */ + NFA_BACKREF9, /* \9 */ ++ #ifdef FEAT_SYN_HL ++ NFA_ZREF1, /* \z1 */ ++ NFA_ZREF2, /* \z2 */ ++ NFA_ZREF3, /* \z3 */ ++ NFA_ZREF4, /* \z4 */ ++ NFA_ZREF5, /* \z5 */ ++ NFA_ZREF6, /* \z6 */ ++ NFA_ZREF7, /* \z7 */ ++ NFA_ZREF8, /* \z8 */ ++ NFA_ZREF9, /* \z9 */ ++ #endif + NFA_SKIP, /* Skip characters */ + + NFA_MOPEN, +! NFA_MOPEN1, +! NFA_MOPEN2, +! NFA_MOPEN3, +! NFA_MOPEN4, +! NFA_MOPEN5, +! NFA_MOPEN6, +! NFA_MOPEN7, +! NFA_MOPEN8, +! NFA_MOPEN9, +! +! NFA_MCLOSE, +! NFA_MCLOSE1, +! NFA_MCLOSE2, +! NFA_MCLOSE3, +! NFA_MCLOSE4, +! NFA_MCLOSE5, +! NFA_MCLOSE6, +! NFA_MCLOSE7, +! NFA_MCLOSE8, +! NFA_MCLOSE9, +! +! #ifdef FEAT_SYN_HL +! NFA_ZOPEN, +! NFA_ZOPEN1, +! NFA_ZOPEN2, +! NFA_ZOPEN3, +! NFA_ZOPEN4, +! NFA_ZOPEN5, +! NFA_ZOPEN6, +! NFA_ZOPEN7, +! NFA_ZOPEN8, +! NFA_ZOPEN9, +! +! NFA_ZCLOSE, +! NFA_ZCLOSE1, +! NFA_ZCLOSE2, +! NFA_ZCLOSE3, +! NFA_ZCLOSE4, +! NFA_ZCLOSE5, +! NFA_ZCLOSE6, +! NFA_ZCLOSE7, +! NFA_ZCLOSE8, +! NFA_ZCLOSE9, +! #endif + + /* NFA_FIRST_NL */ +! NFA_ANY, /* Match any one character. */ + NFA_ANYOF, /* Match any character in this string. */ + NFA_ANYBUT, /* Match any character not in this string. */ + NFA_IDENT, /* Match identifier char */ +*************** +*** 221,227 **** + static void nfa_save_listids __ARGS((nfa_state_T *start, int *list)); + static void nfa_restore_listids __ARGS((nfa_state_T *start, int *list)); + static int nfa_re_num_cmp __ARGS((long_u val, int op, long_u pos)); +! static long nfa_regtry __ARGS((nfa_state_T *start, colnr_T col)); + static long nfa_regexec_both __ARGS((char_u *line, colnr_T col)); + static regprog_T *nfa_regcomp __ARGS((char_u *expr, int re_flags)); + static int nfa_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col)); +--- 275,281 ---- + static void nfa_save_listids __ARGS((nfa_state_T *start, int *list)); + static void nfa_restore_listids __ARGS((nfa_state_T *start, int *list)); + static int nfa_re_num_cmp __ARGS((long_u val, int op, long_u pos)); +! static long nfa_regtry __ARGS((nfa_regprog_T *prog, colnr_T col)); + static long nfa_regexec_both __ARGS((char_u *line, colnr_T col)); + static regprog_T *nfa_regcomp __ARGS((char_u *expr, int re_flags)); + static int nfa_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col)); +*************** +*** 267,272 **** +--- 321,327 ---- + nfa_has_zend = FALSE; + nfa_has_backref = FALSE; + ++ /* shared with BT engine */ + regcomp_start(expr, re_flags); + + return OK; +*************** +*** 799,804 **** +--- 854,860 ---- + EMIT(NFA_ZEND); + nfa_has_zend = TRUE; + break; ++ #ifdef FEAT_SYN_HL + case '1': + case '2': + case '3': +*************** +*** 808,816 **** + case '7': + case '8': + case '9': + case '(': +! /* TODO: \z1...\z9 and \z( not yet supported */ +! return FAIL; + default: + syntax_error = TRUE; + EMSGN(_("E867: (NFA) Unknown operator '\\z%c'"), +--- 864,882 ---- + case '7': + case '8': + case '9': ++ /* \z1...\z9 */ ++ EMIT(NFA_ZREF1 + (no_Magic(c) - '1')); ++ /* No need to set nfa_has_backref, the sub-matches don't ++ * change when \z1 .. \z9 maches or not. */ ++ re_has_z = REX_USE; ++ break; + case '(': +! /* \z( */ +! if (nfa_reg(REG_ZPAREN) == FAIL) +! return FAIL; /* cascaded error */ +! re_has_z = REX_SET; +! break; +! #endif + default: + syntax_error = TRUE; + EMSGN(_("E867: (NFA) Unknown operator '\\z%c'"), +*************** +*** 1651,1658 **** + { + int parno = 0; + +- #ifdef FEAT_SYN_HL +- #endif + if (paren == REG_PAREN) + { + if (regnpar >= NSUBEXP) /* Too many `(' */ +--- 1717,1722 ---- +*************** +*** 1662,1667 **** +--- 1726,1743 ---- + } + parno = regnpar++; + } ++ #ifdef FEAT_SYN_HL ++ else if (paren == REG_ZPAREN) ++ { ++ /* Make a ZOPEN node. */ ++ if (regnzpar >= NSUBEXP) ++ { ++ syntax_error = TRUE; ++ EMSG_RET_FAIL(_("E879: (NFA regexp) Too many \\z(")); ++ } ++ parno = regnzpar++; ++ } ++ #endif + + if (nfa_regbranch() == FAIL) + return FAIL; /* cascaded error */ +*************** +*** 1700,1705 **** +--- 1776,1785 ---- + had_endbrace[parno] = TRUE; /* have seen the close paren */ + EMIT(NFA_MOPEN + parno); + } ++ #ifdef FEAT_SYN_HL ++ else if (paren == REG_ZPAREN) ++ EMIT(NFA_ZOPEN + parno); ++ #endif + + return OK; + } +*************** +*** 1738,1743 **** +--- 1818,1834 ---- + case NFA_BACKREF7: STRCPY(code, "NFA_BACKREF7"); break; + case NFA_BACKREF8: STRCPY(code, "NFA_BACKREF8"); break; + case NFA_BACKREF9: STRCPY(code, "NFA_BACKREF9"); break; ++ #ifdef FEAT_SYN_HL ++ case NFA_ZREF1: STRCPY(code, "NFA_ZREF1"); break; ++ case NFA_ZREF2: STRCPY(code, "NFA_ZREF2"); break; ++ case NFA_ZREF3: STRCPY(code, "NFA_ZREF3"); break; ++ case NFA_ZREF4: STRCPY(code, "NFA_ZREF4"); break; ++ case NFA_ZREF5: STRCPY(code, "NFA_ZREF5"); break; ++ case NFA_ZREF6: STRCPY(code, "NFA_ZREF6"); break; ++ case NFA_ZREF7: STRCPY(code, "NFA_ZREF7"); break; ++ case NFA_ZREF8: STRCPY(code, "NFA_ZREF8"); break; ++ case NFA_ZREF9: STRCPY(code, "NFA_ZREF9"); break; ++ #endif + case NFA_SKIP: STRCPY(code, "NFA_SKIP"); break; + + case NFA_PREV_ATOM_NO_WIDTH: +*************** +*** 1758,1789 **** + case NFA_COMPOSING: STRCPY(code, "NFA_COMPOSING"); break; + case NFA_END_COMPOSING: STRCPY(code, "NFA_END_COMPOSING"); break; + +! case NFA_MOPEN + 0: +! case NFA_MOPEN + 1: +! case NFA_MOPEN + 2: +! case NFA_MOPEN + 3: +! case NFA_MOPEN + 4: +! case NFA_MOPEN + 5: +! case NFA_MOPEN + 6: +! case NFA_MOPEN + 7: +! case NFA_MOPEN + 8: +! case NFA_MOPEN + 9: + STRCPY(code, "NFA_MOPEN(x)"); + code[10] = c - NFA_MOPEN + '0'; + break; +! case NFA_MCLOSE + 0: +! case NFA_MCLOSE + 1: +! case NFA_MCLOSE + 2: +! case NFA_MCLOSE + 3: +! case NFA_MCLOSE + 4: +! case NFA_MCLOSE + 5: +! case NFA_MCLOSE + 6: +! case NFA_MCLOSE + 7: +! case NFA_MCLOSE + 8: +! case NFA_MCLOSE + 9: + STRCPY(code, "NFA_MCLOSE(x)"); + code[11] = c - NFA_MCLOSE + '0'; + break; + case NFA_EOL: STRCPY(code, "NFA_EOL "); break; + case NFA_BOL: STRCPY(code, "NFA_BOL "); break; + case NFA_EOW: STRCPY(code, "NFA_EOW "); break; +--- 1849,1908 ---- + case NFA_COMPOSING: STRCPY(code, "NFA_COMPOSING"); break; + case NFA_END_COMPOSING: STRCPY(code, "NFA_END_COMPOSING"); break; + +! case NFA_MOPEN: +! case NFA_MOPEN1: +! case NFA_MOPEN2: +! case NFA_MOPEN3: +! case NFA_MOPEN4: +! case NFA_MOPEN5: +! case NFA_MOPEN6: +! case NFA_MOPEN7: +! case NFA_MOPEN8: +! case NFA_MOPEN9: + STRCPY(code, "NFA_MOPEN(x)"); + code[10] = c - NFA_MOPEN + '0'; + break; +! case NFA_MCLOSE: +! case NFA_MCLOSE1: +! case NFA_MCLOSE2: +! case NFA_MCLOSE3: +! case NFA_MCLOSE4: +! case NFA_MCLOSE5: +! case NFA_MCLOSE6: +! case NFA_MCLOSE7: +! case NFA_MCLOSE8: +! case NFA_MCLOSE9: + STRCPY(code, "NFA_MCLOSE(x)"); + code[11] = c - NFA_MCLOSE + '0'; + break; ++ #ifdef FEAT_SYN_HL ++ case NFA_ZOPEN: ++ case NFA_ZOPEN1: ++ case NFA_ZOPEN2: ++ case NFA_ZOPEN3: ++ case NFA_ZOPEN4: ++ case NFA_ZOPEN5: ++ case NFA_ZOPEN6: ++ case NFA_ZOPEN7: ++ case NFA_ZOPEN8: ++ case NFA_ZOPEN9: ++ STRCPY(code, "NFA_ZOPEN(x)"); ++ code[10] = c - NFA_ZOPEN + '0'; ++ break; ++ case NFA_ZCLOSE: ++ case NFA_ZCLOSE1: ++ case NFA_ZCLOSE2: ++ case NFA_ZCLOSE3: ++ case NFA_ZCLOSE4: ++ case NFA_ZCLOSE5: ++ case NFA_ZCLOSE6: ++ case NFA_ZCLOSE7: ++ case NFA_ZCLOSE8: ++ case NFA_ZCLOSE9: ++ STRCPY(code, "NFA_ZCLOSE(x)"); ++ code[11] = c - NFA_ZCLOSE + '0'; ++ break; ++ #endif + case NFA_EOL: STRCPY(code, "NFA_EOL "); break; + case NFA_BOL: STRCPY(code, "NFA_BOL "); break; + case NFA_EOW: STRCPY(code, "NFA_EOW "); break; +*************** +*** 2437,2453 **** + /* FALLTHROUGH */ + #endif + +! case NFA_MOPEN + 0: /* Submatch */ +! case NFA_MOPEN + 1: +! case NFA_MOPEN + 2: +! case NFA_MOPEN + 3: +! case NFA_MOPEN + 4: +! case NFA_MOPEN + 5: +! case NFA_MOPEN + 6: +! case NFA_MOPEN + 7: +! case NFA_MOPEN + 8: +! case NFA_MOPEN + 9: +! case NFA_NOPEN: /* \%( "Invisible Submatch" */ + if (nfa_calc_size == TRUE) + { + nstate += 2; +--- 2556,2584 ---- + /* FALLTHROUGH */ + #endif + +! case NFA_MOPEN: /* \( \) Submatch */ +! case NFA_MOPEN1: +! case NFA_MOPEN2: +! case NFA_MOPEN3: +! case NFA_MOPEN4: +! case NFA_MOPEN5: +! case NFA_MOPEN6: +! case NFA_MOPEN7: +! case NFA_MOPEN8: +! case NFA_MOPEN9: +! #ifdef FEAT_SYN_HL +! case NFA_ZOPEN: /* \z( \) Submatch */ +! case NFA_ZOPEN1: +! case NFA_ZOPEN2: +! case NFA_ZOPEN3: +! case NFA_ZOPEN4: +! case NFA_ZOPEN5: +! case NFA_ZOPEN6: +! case NFA_ZOPEN7: +! case NFA_ZOPEN8: +! case NFA_ZOPEN9: +! #endif +! case NFA_NOPEN: /* \%( \) "Invisible Submatch" */ + if (nfa_calc_size == TRUE) + { + nstate += 2; +*************** +*** 2457,2472 **** + mopen = *p; + switch (*p) + { +! case NFA_NOPEN: +! mclose = NFA_NCLOSE; +! break; + #ifdef FEAT_MBYTE +! case NFA_COMPOSING: +! mclose = NFA_END_COMPOSING; +! break; + #endif + default: +! /* NFA_MOPEN(0) ... NFA_MOPEN(9) */ + mclose = *p + NSUBEXP; + break; + } +--- 2588,2611 ---- + mopen = *p; + switch (*p) + { +! case NFA_NOPEN: mclose = NFA_NCLOSE; break; +! #ifdef FEAT_SYN_HL +! case NFA_ZOPEN: mclose = NFA_ZCLOSE; break; +! case NFA_ZOPEN1: mclose = NFA_ZCLOSE1; break; +! case NFA_ZOPEN2: mclose = NFA_ZCLOSE2; break; +! case NFA_ZOPEN3: mclose = NFA_ZCLOSE3; break; +! case NFA_ZOPEN4: mclose = NFA_ZCLOSE4; break; +! case NFA_ZOPEN5: mclose = NFA_ZCLOSE5; break; +! case NFA_ZOPEN6: mclose = NFA_ZCLOSE6; break; +! case NFA_ZOPEN7: mclose = NFA_ZCLOSE7; break; +! case NFA_ZOPEN8: mclose = NFA_ZCLOSE8; break; +! case NFA_ZOPEN9: mclose = NFA_ZCLOSE9; break; +! #endif + #ifdef FEAT_MBYTE +! case NFA_COMPOSING: mclose = NFA_END_COMPOSING; break; + #endif + default: +! /* NFA_MOPEN, NFA_MOPEN1 .. NFA_MOPEN9 */ + mclose = *p + NSUBEXP; + break; + } +*************** +*** 2518,2523 **** +--- 2657,2673 ---- + case NFA_BACKREF7: + case NFA_BACKREF8: + case NFA_BACKREF9: ++ #ifdef FEAT_SYN_HL ++ case NFA_ZREF1: ++ case NFA_ZREF2: ++ case NFA_ZREF3: ++ case NFA_ZREF4: ++ case NFA_ZREF5: ++ case NFA_ZREF6: ++ case NFA_ZREF7: ++ case NFA_ZREF8: ++ case NFA_ZREF9: ++ #endif + if (nfa_calc_size == TRUE) + { + nstate += 2; +*************** +*** 2630,2641 **** + } list; + } regsub_T; + + /* nfa_thread_T contains execution information of a NFA state */ + typedef struct + { + nfa_state_T *state; + int count; +! regsub_T sub; /* submatch info, only party used */ + } nfa_thread_T; + + /* nfa_list_T contains the alternative NFA execution states. */ +--- 2780,2799 ---- + } list; + } regsub_T; + ++ typedef struct ++ { ++ regsub_T norm; /* \( .. \) matches */ ++ #ifdef FEAT_SYN_HL ++ regsub_T synt; /* \z( .. \) matches */ ++ #endif ++ } regsubs_T; ++ + /* nfa_thread_T contains execution information of a NFA state */ + typedef struct + { + nfa_state_T *state; + int count; +! regsubs_T subs; /* submatch info, only party used */ + } nfa_thread_T; + + /* nfa_list_T contains the alternative NFA execution states. */ +*************** +*** 2648,2653 **** +--- 2806,2824 ---- + } nfa_list_T; + + #ifdef ENABLE_LOG ++ static void log_subsexpr __ARGS((regsubs_T *subs)); ++ static void log_subexpr __ARGS((regsub_T *sub)); ++ ++ static void ++ log_subsexpr(subs) ++ regsubs_T *subs; ++ { ++ log_subexpr(&subs->norm); ++ # ifdef FEAT_SYN_HL ++ log_subexpr(&subs->synt); ++ # endif ++ } ++ + static void + log_subexpr(sub) + regsub_T *sub; +*************** +*** 2674,2682 **** + /* Used during execution: whether a match has been found. */ + static int nfa_match; + + static int sub_equal __ARGS((regsub_T *sub1, regsub_T *sub2)); +! static void addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsub_T *sub, int off)); +! static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state, regsub_T *sub, int *ip)); + + /* + * Return TRUE if "sub1" and "sub2" have the same positions. +--- 2845,2916 ---- + /* Used during execution: whether a match has been found. */ + static int nfa_match; + ++ static void clear_sub __ARGS((regsub_T *sub)); ++ static void copy_sub __ARGS((regsub_T *to, regsub_T *from)); ++ static void copy_sub_off __ARGS((regsub_T *to, regsub_T *from)); + static int sub_equal __ARGS((regsub_T *sub1, regsub_T *sub2)); +! static void addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, int off)); +! static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, int *ip)); +! +! static void +! clear_sub(sub) +! regsub_T *sub; +! { +! if (REG_MULTI) +! /* Use 0xff to set lnum to -1 */ +! vim_memset(sub->list.multi, 0xff, +! sizeof(struct multipos) * nfa_nsubexpr); +! else +! vim_memset(sub->list.line, 0, sizeof(struct linepos) * nfa_nsubexpr); +! sub->in_use = 0; +! } +! +! /* +! * Copy the submatches from "from" to "to". +! */ +! static void +! copy_sub(to, from) +! regsub_T *to; +! regsub_T *from; +! { +! to->in_use = from->in_use; +! if (from->in_use > 0) +! { +! /* Copy the match start and end positions. */ +! if (REG_MULTI) +! mch_memmove(&to->list.multi[0], +! &from->list.multi[0], +! sizeof(struct multipos) * from->in_use); +! else +! mch_memmove(&to->list.line[0], +! &from->list.line[0], +! sizeof(struct linepos) * from->in_use); +! } +! } +! +! /* +! * Like copy_sub() but exclude the main match. +! */ +! static void +! copy_sub_off(to, from) +! regsub_T *to; +! regsub_T *from; +! { +! if (to->in_use < from->in_use) +! to->in_use = from->in_use; +! if (from->in_use > 1) +! { +! /* Copy the match start and end positions. */ +! if (REG_MULTI) +! mch_memmove(&to->list.multi[1], +! &from->list.multi[1], +! sizeof(struct multipos) * (from->in_use - 1)); +! else +! mch_memmove(&to->list.line[1], +! &from->list.line[1], +! sizeof(struct linepos) * (from->in_use - 1)); +! } +! } + + /* + * Return TRUE if "sub1" and "sub2" have the same positions. +*************** +*** 2761,2770 **** + } + + static void +! addstate(l, state, sub, off) + nfa_list_T *l; /* runtime state list */ + nfa_state_T *state; /* state to update */ +! regsub_T *sub; /* pointers to subexpressions */ + int off; /* byte offset, when -1 go to next line */ + { + int subidx; +--- 2995,3004 ---- + } + + static void +! addstate(l, state, subs, off) + nfa_list_T *l; /* runtime state list */ + nfa_state_T *state; /* state to update */ +! regsubs_T *subs; /* pointers to subexpressions */ + int off; /* byte offset, when -1 go to next line */ + { + int subidx; +*************** +*** 2773,2778 **** +--- 3007,3013 ---- + int save_in_use; + char_u *save_ptr; + int i; ++ regsub_T *sub; + #ifdef ENABLE_LOG + int did_print = FALSE; + #endif +*************** +*** 2787,2815 **** + case NFA_NOPEN: + case NFA_NCLOSE: + case NFA_MCLOSE: +! case NFA_MCLOSE + 1: +! case NFA_MCLOSE + 2: +! case NFA_MCLOSE + 3: +! case NFA_MCLOSE + 4: +! case NFA_MCLOSE + 5: +! case NFA_MCLOSE + 6: +! case NFA_MCLOSE + 7: +! case NFA_MCLOSE + 8: +! case NFA_MCLOSE + 9: + /* These nodes are not added themselves but their "out" and/or + * "out1" may be added below. */ + break; + + case NFA_MOPEN: +! case NFA_MOPEN + 1: +! case NFA_MOPEN + 2: +! case NFA_MOPEN + 3: +! case NFA_MOPEN + 4: +! case NFA_MOPEN + 5: +! case NFA_MOPEN + 6: +! case NFA_MOPEN + 7: +! case NFA_MOPEN + 8: +! case NFA_MOPEN + 9: + /* These nodes do not need to be added, but we need to bail out + * when it was tried to be added to this list before. */ + if (state->lastlist == l->id) +--- 3022,3074 ---- + case NFA_NOPEN: + case NFA_NCLOSE: + case NFA_MCLOSE: +! case NFA_MCLOSE1: +! case NFA_MCLOSE2: +! case NFA_MCLOSE3: +! case NFA_MCLOSE4: +! case NFA_MCLOSE5: +! case NFA_MCLOSE6: +! case NFA_MCLOSE7: +! case NFA_MCLOSE8: +! case NFA_MCLOSE9: +! #ifdef FEAT_SYN_HL +! case NFA_ZCLOSE: +! case NFA_ZCLOSE1: +! case NFA_ZCLOSE2: +! case NFA_ZCLOSE3: +! case NFA_ZCLOSE4: +! case NFA_ZCLOSE5: +! case NFA_ZCLOSE6: +! case NFA_ZCLOSE7: +! case NFA_ZCLOSE8: +! case NFA_ZCLOSE9: +! #endif + /* These nodes are not added themselves but their "out" and/or + * "out1" may be added below. */ + break; + + case NFA_MOPEN: +! case NFA_MOPEN1: +! case NFA_MOPEN2: +! case NFA_MOPEN3: +! case NFA_MOPEN4: +! case NFA_MOPEN5: +! case NFA_MOPEN6: +! case NFA_MOPEN7: +! case NFA_MOPEN8: +! case NFA_MOPEN9: +! #ifdef FEAT_SYN_HL +! case NFA_ZOPEN: +! case NFA_ZOPEN1: +! case NFA_ZOPEN2: +! case NFA_ZOPEN3: +! case NFA_ZOPEN4: +! case NFA_ZOPEN5: +! case NFA_ZOPEN6: +! case NFA_ZOPEN7: +! case NFA_ZOPEN8: +! case NFA_ZOPEN9: +! #endif + /* These nodes do not need to be added, but we need to bail out + * when it was tried to be added to this list before. */ + if (state->lastlist == l->id) +*************** +*** 2839,2845 **** + { + thread = &l->t[i]; + if (thread->state->id == state->id +! && sub_equal(&thread->sub, sub)) + goto skip_add; + } + } +--- 3098,3108 ---- + { + thread = &l->t[i]; + if (thread->state->id == state->id +! && sub_equal(&thread->subs.norm, &subs->norm) +! #ifdef FEAT_SYN_HL +! && sub_equal(&thread->subs.synt, &subs->synt) +! #endif +! ) + goto skip_add; + } + } +*************** +*** 2858,2876 **** + state->lastlist = l->id; + thread = &l->t[l->n++]; + thread->state = state; +! thread->sub.in_use = sub->in_use; +! if (sub->in_use > 0) +! { +! /* Copy the match start and end positions. */ +! if (REG_MULTI) +! mch_memmove(&thread->sub.list.multi[0], +! &sub->list.multi[0], +! sizeof(struct multipos) * sub->in_use); +! else +! mch_memmove(&thread->sub.list.line[0], +! &sub->list.line[0], +! sizeof(struct linepos) * sub->in_use); +! } + #ifdef ENABLE_LOG + { + int col; +--- 3121,3130 ---- + state->lastlist = l->id; + thread = &l->t[l->n++]; + thread->state = state; +! copy_sub(&thread->subs.norm, &subs->norm); +! #ifdef FEAT_SYN_HL +! copy_sub(&thread->subs.synt, &subs->synt); +! #endif + #ifdef ENABLE_LOG + { + int col; +*************** +*** 2912,2959 **** + break; + + case NFA_SPLIT: +! addstate(l, state->out, sub, off); +! addstate(l, state->out1, sub, off); + break; + +- #if 0 +- case NFA_END_NEG_RANGE: +- /* Nothing to handle here. nfa_regmatch() will take care of it */ +- break; +- +- case NFA_NOT: +- EMSG(_("E999: (NFA regexp internal error) Should not process NOT node !")); +- #ifdef ENABLE_LOG +- fprintf(f, "\n\n>>> E999: Added state NFA_NOT to a list ... Something went wrong ! Why wasn't it processed already? \n\n"); +- #endif +- break; +- +- case NFA_COMPOSING: +- /* nfa_regmatch() will match all the bytes of this composing char. */ +- break; +- #endif +- + case NFA_SKIP_CHAR: + case NFA_NOPEN: + case NFA_NCLOSE: +! addstate(l, state->out, sub, off); + break; + +! case NFA_MOPEN + 0: +! case NFA_MOPEN + 1: +! case NFA_MOPEN + 2: +! case NFA_MOPEN + 3: +! case NFA_MOPEN + 4: +! case NFA_MOPEN + 5: +! case NFA_MOPEN + 6: +! case NFA_MOPEN + 7: +! case NFA_MOPEN + 8: +! case NFA_MOPEN + 9: + case NFA_ZSTART: + if (state->c == NFA_ZSTART) + subidx = 0; + else + subidx = state->c - NFA_MOPEN; + + /* Set the position (with "off") in the subexpression. Save and + * restore it when it was in use. Otherwise fill any gap. */ +--- 3166,3222 ---- + break; + + case NFA_SPLIT: +! /* order matters here */ +! addstate(l, state->out, subs, off); +! addstate(l, state->out1, subs, off); + break; + + case NFA_SKIP_CHAR: + case NFA_NOPEN: + case NFA_NCLOSE: +! addstate(l, state->out, subs, off); + break; + +! case NFA_MOPEN: +! case NFA_MOPEN1: +! case NFA_MOPEN2: +! case NFA_MOPEN3: +! case NFA_MOPEN4: +! case NFA_MOPEN5: +! case NFA_MOPEN6: +! case NFA_MOPEN7: +! case NFA_MOPEN8: +! case NFA_MOPEN9: +! #ifdef FEAT_SYN_HL +! case NFA_ZOPEN: +! case NFA_ZOPEN1: +! case NFA_ZOPEN2: +! case NFA_ZOPEN3: +! case NFA_ZOPEN4: +! case NFA_ZOPEN5: +! case NFA_ZOPEN6: +! case NFA_ZOPEN7: +! case NFA_ZOPEN8: +! case NFA_ZOPEN9: +! #endif + case NFA_ZSTART: + if (state->c == NFA_ZSTART) ++ { + subidx = 0; ++ sub = &subs->norm; ++ } ++ #ifdef FEAT_SYN_HL ++ else if (state->c >= NFA_ZOPEN) ++ { ++ subidx = state->c - NFA_ZOPEN; ++ sub = &subs->synt; ++ } ++ #endif + else ++ { + subidx = state->c - NFA_MOPEN; ++ sub = &subs->norm; ++ } + + /* Set the position (with "off") in the subexpression. Save and + * restore it when it was in use. Otherwise fill any gap. */ +*************** +*** 3007,3013 **** + sub->list.line[subidx].start = reginput + off; + } + +! addstate(l, state->out, sub, off); + + if (save_in_use == -1) + { +--- 3270,3276 ---- + sub->list.line[subidx].start = reginput + off; + } + +! addstate(l, state->out, subs, off); + + if (save_in_use == -1) + { +*************** +*** 3020,3047 **** + sub->in_use = save_in_use; + break; + +! case NFA_MCLOSE + 0: + if (nfa_has_zend) + { + /* Do not overwrite the position set by \ze. If no \ze + * encountered end will be set in nfa_regtry(). */ +! addstate(l, state->out, sub, off); + break; + } +! case NFA_MCLOSE + 1: +! case NFA_MCLOSE + 2: +! case NFA_MCLOSE + 3: +! case NFA_MCLOSE + 4: +! case NFA_MCLOSE + 5: +! case NFA_MCLOSE + 6: +! case NFA_MCLOSE + 7: +! case NFA_MCLOSE + 8: +! case NFA_MCLOSE + 9: + case NFA_ZEND: + if (state->c == NFA_ZEND) + subidx = 0; + else + subidx = state->c - NFA_MCLOSE; + + /* We don't fill in gaps here, there must have been an MOPEN that + * has done that. */ +--- 3283,3335 ---- + sub->in_use = save_in_use; + break; + +! case NFA_MCLOSE: + if (nfa_has_zend) + { + /* Do not overwrite the position set by \ze. If no \ze + * encountered end will be set in nfa_regtry(). */ +! addstate(l, state->out, subs, off); + break; + } +! case NFA_MCLOSE1: +! case NFA_MCLOSE2: +! case NFA_MCLOSE3: +! case NFA_MCLOSE4: +! case NFA_MCLOSE5: +! case NFA_MCLOSE6: +! case NFA_MCLOSE7: +! case NFA_MCLOSE8: +! case NFA_MCLOSE9: +! #ifdef FEAT_SYN_HL +! case NFA_ZCLOSE: +! case NFA_ZCLOSE1: +! case NFA_ZCLOSE2: +! case NFA_ZCLOSE3: +! case NFA_ZCLOSE4: +! case NFA_ZCLOSE5: +! case NFA_ZCLOSE6: +! case NFA_ZCLOSE7: +! case NFA_ZCLOSE8: +! case NFA_ZCLOSE9: +! #endif + case NFA_ZEND: + if (state->c == NFA_ZEND) ++ { + subidx = 0; ++ sub = &subs->norm; ++ } ++ #ifdef FEAT_SYN_HL ++ else if (state->c >= NFA_ZCLOSE) ++ { ++ subidx = state->c - NFA_ZCLOSE; ++ sub = &subs->synt; ++ } ++ #endif + else ++ { + subidx = state->c - NFA_MCLOSE; ++ sub = &subs->norm; ++ } + + /* We don't fill in gaps here, there must have been an MOPEN that + * has done that. */ +*************** +*** 3069,3075 **** + sub->list.line[subidx].end = reginput + off; + } + +! addstate(l, state->out, sub, off); + + if (REG_MULTI) + sub->list.multi[subidx].end = save_lpos; +--- 3357,3363 ---- + sub->list.line[subidx].end = reginput + off; + } + +! addstate(l, state->out, subs, off); + + if (REG_MULTI) + sub->list.multi[subidx].end = save_lpos; +*************** +*** 3087,3096 **** + * matters for alternatives. + */ + static void +! addstate_here(l, state, sub, ip) + nfa_list_T *l; /* runtime state list */ + nfa_state_T *state; /* state to update */ +! regsub_T *sub; /* pointers to subexpressions */ + int *ip; + { + int tlen = l->n; +--- 3375,3384 ---- + * matters for alternatives. + */ + static void +! addstate_here(l, state, subs, ip) + nfa_list_T *l; /* runtime state list */ + nfa_state_T *state; /* state to update */ +! regsubs_T *subs; /* pointers to subexpressions */ + int *ip; + { + int tlen = l->n; +*************** +*** 3098,3104 **** + int i = *ip; + + /* first add the state(s) at the end, so that we know how many there are */ +! addstate(l, state, sub, 0); + + /* when "*ip" was at the end of the list, nothing to do */ + if (i + 1 == tlen) +--- 3386,3392 ---- + int i = *ip; + + /* first add the state(s) at the end, so that we know how many there are */ +! addstate(l, state, subs, 0); + + /* when "*ip" was at the end of the list, nothing to do */ + if (i + 1 == tlen) +*************** +*** 3212,3218 **** + + /* + * Check for a match with subexpression "subidx". +! * return TRUE if it matches. + */ + static int + match_backref(sub, subidx, bytelen) +--- 3500,3506 ---- + + /* + * Check for a match with subexpression "subidx". +! * Return TRUE if it matches. + */ + static int + match_backref(sub, subidx, bytelen) +*************** +*** 3260,3265 **** +--- 3548,3586 ---- + return FALSE; + } + ++ #ifdef FEAT_SYN_HL ++ ++ static int match_zref __ARGS((int subidx, int *bytelen)); ++ ++ /* ++ * Check for a match with \z subexpression "subidx". ++ * Return TRUE if it matches. ++ */ ++ static int ++ match_zref(subidx, bytelen) ++ int subidx; ++ int *bytelen; /* out: length of match in bytes */ ++ { ++ int len; ++ ++ cleanup_zsubexpr(); ++ if (re_extmatch_in == NULL || re_extmatch_in->matches[subidx] == NULL) ++ { ++ /* backref was not set, match an empty string */ ++ *bytelen = 0; ++ return TRUE; ++ } ++ ++ len = (int)STRLEN(re_extmatch_in->matches[subidx]); ++ if (cstrncmp(re_extmatch_in->matches[subidx], reginput, &len) == 0) ++ { ++ *bytelen = len; ++ return TRUE; ++ } ++ return FALSE; ++ } ++ #endif ++ + /* + * Set all NFA nodes' list ID equal to -1. + */ +*************** +*** 3334,3340 **** + return val == pos; + } + +! static int nfa_regmatch __ARGS((nfa_state_T *start, regsub_T *submatch, regsub_T *m, save_se_T *endp)); + + /* + * Main matching routine. +--- 3655,3661 ---- + return val == pos; + } + +! static int nfa_regmatch __ARGS((nfa_state_T *start, regsubs_T *submatch, regsubs_T *m, save_se_T *endp)); + + /* + * Main matching routine. +*************** +*** 3349,3356 **** + static int + nfa_regmatch(start, submatch, m, endp) + nfa_state_T *start; +! regsub_T *submatch; +! regsub_T *m; + save_se_T *endp; + { + int result; +--- 3670,3677 ---- + static int + nfa_regmatch(start, submatch, m, endp) + nfa_state_T *start; +! regsubs_T *submatch; +! regsubs_T *m; + save_se_T *endp; + { + int result; +*************** +*** 3429,3435 **** + #define ADD_POS_NEG_STATE(node) \ + ll = listtbl[result ? 1 : 0][node->negated]; \ + if (ll != NULL) \ +! addstate(ll, node->out , &t->sub, clen); + + + /* +--- 3750,3756 ---- + #define ADD_POS_NEG_STATE(node) \ + ll = listtbl[result ? 1 : 0][node->negated]; \ + if (ll != NULL) \ +! addstate(ll, node->out , &t->subs, clen); + + + /* +*************** +*** 3531,3556 **** + { + case NFA_MATCH: + { +- int j; +- + nfa_match = TRUE; +! submatch->in_use = t->sub.in_use; +! if (REG_MULTI) +! for (j = 0; j < submatch->in_use; j++) +! { +! submatch->list.multi[j].start = +! t->sub.list.multi[j].start; +! submatch->list.multi[j].end = t->sub.list.multi[j].end; +! } +! else +! for (j = 0; j < submatch->in_use; j++) +! { +! submatch->list.line[j].start = +! t->sub.list.line[j].start; +! submatch->list.line[j].end = t->sub.list.line[j].end; +! } + #ifdef ENABLE_LOG +! log_subexpr(&t->sub); + #endif + /* Found the left-most longest match, do not look at any other + * states at this position. When the list of states is going +--- 3852,3864 ---- + { + case NFA_MATCH: + { + nfa_match = TRUE; +! copy_sub(&submatch->norm, &t->subs.norm); +! #ifdef FEAT_SYN_HL +! copy_sub(&submatch->synt, &t->subs.synt); +! #endif + #ifdef ENABLE_LOG +! log_subsexpr(&t->subs); + #endif + /* Found the left-most longest match, do not look at any other + * states at this position. When the list of states is going +*************** +*** 3570,3578 **** + * finished successfully, so return control to the parent + * nfa_regmatch(). Submatches are stored in *m, and used in + * the parent call. */ +! if (start->c == NFA_MOPEN + 0) + /* TODO: do we ever get here? */ +! addstate_here(thislist, t->state->out, &t->sub, &listidx); + else + { + #ifdef ENABLE_LOG +--- 3878,3886 ---- + * finished successfully, so return control to the parent + * nfa_regmatch(). Submatches are stored in *m, and used in + * the parent call. */ +! if (start->c == NFA_MOPEN) + /* TODO: do we ever get here? */ +! addstate_here(thislist, t->state->out, &t->subs, &listidx); + else + { + #ifdef ENABLE_LOG +*************** +*** 3600,3607 **** + + /* do not set submatches for \@! */ + if (!t->state->negated) +! /* TODO: only copy positions in use. */ +! *m = t->sub; + nfa_match = TRUE; + } + break; +--- 3908,3919 ---- + + /* do not set submatches for \@! */ + if (!t->state->negated) +! { +! copy_sub(&m->norm, &t->subs.norm); +! #ifdef FEAT_SYN_HL +! copy_sub(&m->synt, &t->subs.synt); +! #endif +! } + nfa_match = TRUE; + } + break; +*************** +*** 3630,3636 **** + + /* Go back the specified number of bytes, or as far as the + * start of the previous line, to try matching "\@<=" or +! * not matching "\@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 "\@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@Moolenaar.net -- http://www.Moolenaar.net \\\ +/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ +\\\ an exciting new programming language -- http://www.Zimbu.org /// + \\\ help me help AIDS victims -- http://ICCF-Holland.org ///