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 ///