[vim] - patchlevel 1110
Karsten Hopp
karsten at fedoraproject.org
Thu Jun 13 22:29:42 UTC 2013
commit 3c6980664afd15e6275a26209ec48eefeebb7ba8
Author: Karsten Hopp <karsten at redhat.com>
Date: Fri Jun 14 00:27:53 2013 +0200
- patchlevel 1110
7.3.1110 | 842 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 842 insertions(+), 0 deletions(-)
---
diff --git a/7.3.1110 b/7.3.1110
new file mode 100644
index 0000000..a8944bf
--- /dev/null
+++ b/7.3.1110
@@ -0,0 +1,842 @@
+To: vim_dev at googlegroups.com
+Subject: Patch 7.3.1110
+Fcc: outbox
+From: Bram Moolenaar <Bram at moolenaar.net>
+Mime-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+------------
+
+Patch 7.3.1110
+Problem: New regexp matching: Using \@= and the like can be slow.
+Solution: Decide whether to first try matching the zero-wdith part or what
+ follows, whatever is more likely to fail.
+Files: src/regexp_nfa.c
+
+
+*** ../vim-7.3.1109/src/regexp_nfa.c 2013-06-03 19:41:01.000000000 +0200
+--- src/regexp_nfa.c 2013-06-04 14:21:32.000000000 +0200
+***************
+*** 2824,2834 ****
+--- 2824,2851 ----
+ #endif
+ } regsubs_T;
+
++ /* nfa_pim_T stores a Postponed Invisible Match. */
++ typedef struct nfa_pim_S nfa_pim_T;
++ struct nfa_pim_S
++ {
++ nfa_state_T *state;
++ int result; /* NFA_PIM_TODO, NFA_PIM_[NO]MATCH */
++ nfa_pim_T *pim; /* another PIM at the same position */
++ regsubs_T subs; /* submatch info, only party used */
++ };
++
++ /* Values for done in nfa_pim_T. */
++ #define NFA_PIM_TODO 0
++ #define NFA_PIM_MATCH 1
++ #define NFA_PIM_NOMATCH -1
++
++
+ /* nfa_thread_T contains execution information of a NFA state */
+ typedef struct
+ {
+ nfa_state_T *state;
+ int count;
++ nfa_pim_T *pim; /* if not NULL: postponed invisible match */
+ regsubs_T subs; /* submatch info, only party used */
+ } nfa_thread_T;
+
+***************
+*** 2886,2892 ****
+ 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)
+--- 2903,2909 ----
+ 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, nfa_pim_T *pim, int *ip));
+
+ static void
+ clear_sub(sub)
+***************
+*** 3032,3038 ****
+
+ #ifdef ENABLE_LOG
+ static void
+! report_state(char *action, regsub_T *sub, nfa_state_T *state, int lid);
+ {
+ int col;
+
+--- 3049,3055 ----
+
+ #ifdef ENABLE_LOG
+ static void
+! report_state(char *action, regsub_T *sub, nfa_state_T *state, int lid)
+ {
+ int col;
+
+***************
+*** 3174,3181 ****
+ }
+ }
+
+! /* when there are backreferences the number of states may be (a
+! * lot) bigger */
+ if (nfa_has_backref && l->n == l->len)
+ {
+ int newlen = l->len * 3 / 2 + 50;
+--- 3191,3198 ----
+ }
+ }
+
+! /* when there are backreferences or look-behind matches the number
+! * of states may be (a lot) bigger */
+ if (nfa_has_backref && l->n == l->len)
+ {
+ int newlen = l->len * 3 / 2 + 50;
+***************
+*** 3188,3193 ****
+--- 3205,3211 ----
+ state->lastlist[nfa_ll_index] = l->id;
+ thread = &l->t[l->n++];
+ thread->state = state;
++ thread->pim = NULL;
+ copy_sub(&thread->subs.norm, &subs->norm);
+ #ifdef FEAT_SYN_HL
+ if (nfa_has_zsubexpr)
+***************
+*** 3419,3439 ****
+ * 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;
+ int count;
+! 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)
+ return;
+
+ /* re-order to put the new state at the current position */
+--- 3437,3464 ----
+ * matters for alternatives.
+ */
+ static void
+! addstate_here(l, state, subs, pim, ip)
+ nfa_list_T *l; /* runtime state list */
+ nfa_state_T *state; /* state to update */
+ regsubs_T *subs; /* pointers to subexpressions */
++ nfa_pim_T *pim; /* postponed look-behind match */
+ int *ip;
+ {
+ int tlen = l->n;
+ int count;
+! int listidx = *ip;
+! int i;
+
+ /* first add the state(s) at the end, so that we know how many there are */
+ addstate(l, state, subs, 0);
+
++ /* fill in the "pim" field in the new states */
++ if (pim != NULL)
++ for (i = tlen; i < l->n; ++i)
++ l->t[i].pim = pim;
++
+ /* when "*ip" was at the end of the list, nothing to do */
+! if (listidx + 1 == tlen)
+ return;
+
+ /* re-order to put the new state at the current position */
+***************
+*** 3441,3461 ****
+ if (count == 1)
+ {
+ /* overwrite the current state */
+! l->t[i] = l->t[l->n - 1];
+ }
+ else if (count > 1)
+ {
+ /* make space for new states, then move them from the
+ * end to the current position */
+! mch_memmove(&(l->t[i + count]),
+! &(l->t[i + 1]),
+! sizeof(nfa_thread_T) * (l->n - i - 1));
+! mch_memmove(&(l->t[i]),
+ &(l->t[l->n - 1]),
+ sizeof(nfa_thread_T) * count);
+ }
+ --l->n;
+! *ip = i - 1;
+ }
+
+ /*
+--- 3466,3486 ----
+ if (count == 1)
+ {
+ /* overwrite the current state */
+! l->t[listidx] = l->t[l->n - 1];
+ }
+ else if (count > 1)
+ {
+ /* make space for new states, then move them from the
+ * end to the current position */
+! mch_memmove(&(l->t[listidx + count]),
+! &(l->t[listidx + 1]),
+! sizeof(nfa_thread_T) * (l->n - listidx - 1));
+! mch_memmove(&(l->t[listidx]),
+ &(l->t[l->n - 1]),
+ sizeof(nfa_thread_T) * count);
+ }
+ --l->n;
+! *ip = listidx - 1;
+ }
+
+ /*
+***************
+*** 3834,3839 ****
+--- 3859,3903 ----
+ return result;
+ }
+
++ static int failure_chance __ARGS((nfa_state_T *state, int depth));
++
++ /*
++ * Estimate the chance of a match with "state" failing.
++ * NFA_ANY: 1
++ * specific character: 99
++ */
++ static int
++ failure_chance(state, depth)
++ nfa_state_T *state;
++ int depth;
++ {
++ int c = state->c;
++ int l, r;
++
++ /* detect looping */
++ if (depth > 4)
++ return 1;
++
++ if (c == NFA_SPLIT)
++ {
++ if (state->out->c == NFA_SPLIT || state->out1->c == NFA_SPLIT)
++ return 1;
++ l = failure_chance(state->out, depth + 1);
++ r = failure_chance(state->out1, depth + 1);
++ return l < r ? l : r;
++ }
++ if (c == NFA_ANY)
++ return 1;
++ if (c > 0)
++ return 99;
++ if ((c >= NFA_MOPEN && c <= NFA_MOPEN9)
++ || (c >= NFA_ZOPEN && c <= NFA_ZOPEN9)
++ || c == NFA_NOPEN)
++ return failure_chance(state->out, depth + 1);
++ /* something else */
++ return 50;
++ }
++
+ /*
+ * Main matching routine.
+ *
+***************
+*** 3864,3869 ****
+--- 3928,3937 ----
+ nfa_list_T *nextlist;
+ nfa_list_T *neglist;
+ int *listids = NULL;
++ nfa_state_T *add_state;
++ int add_count;
++ int add_off;
++ garray_T pimlist;
+ #ifdef NFA_REGEXP_DEBUG_LOG
+ FILE *debug = fopen(NFA_REGEXP_DEBUG_LOG, "a");
+
+***************
+*** 3874,3879 ****
+--- 3942,3948 ----
+ }
+ #endif
+ nfa_match = FALSE;
++ ga_init2(&pimlist, sizeof(nfa_pim_T), 5);
+
+ /* Allocate memory for the lists of nodes. */
+ size = (nstate + 1) * sizeof(nfa_thread_T);
+***************
+*** 3923,3933 ****
+ listtbl[0][1] = neglist;
+ listtbl[1][0] = nextlist;
+ listtbl[1][1] = NULL;
+! #define ADD_POS_NEG_STATE(node) \
+! ll = listtbl[result ? 1 : 0][node->negated]; \
+! if (ll != NULL) \
+! addstate(ll, node->out , &t->subs, clen);
+!
+
+ /*
+ * Run for each character.
+--- 3992,4003 ----
+ listtbl[0][1] = neglist;
+ listtbl[1][0] = nextlist;
+ listtbl[1][1] = NULL;
+! #define ADD_POS_NEG_STATE(state) \
+! ll = listtbl[result ? 1 : 0][state->negated]; \
+! if (ll != NULL) { \
+! add_state = state->out; \
+! add_off = clen; \
+! }
+
+ /*
+ * Run for each character.
+***************
+*** 3965,3970 ****
+--- 4035,4042 ----
+ nextlist->id = nfa_listid + 1;
+ neglist->id = nfa_listid + 1;
+
++ pimlist.ga_len = 0;
++
+ #ifdef ENABLE_LOG
+ fprintf(log_fd, "------------------------------------------\n");
+ fprintf(log_fd, ">>> Reginput is \"%s\"\n", reginput);
+***************
+*** 4024,4029 ****
+--- 4096,4103 ----
+ * Handle the possible codes of the current state.
+ * The most important is NFA_MATCH.
+ */
++ add_state = NULL;
++ add_count = 0;
+ switch (t->state->c)
+ {
+ case NFA_MATCH:
+***************
+*** 4095,4127 ****
+
+ case NFA_START_INVISIBLE:
+ case NFA_START_INVISIBLE_BEFORE:
+! result = recursive_regmatch(t->state, prog, submatch, m,
+! &listids);
+
+! /* 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 its out to the current list (zero-width match). */
+! addstate_here(thislist, t->state->out1->out, &t->subs,
+! &listidx);
+ }
+ break;
+
+ 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:
+--- 4169,4256 ----
+
+ case NFA_START_INVISIBLE:
+ case NFA_START_INVISIBLE_BEFORE:
+! /* If invisible match has a higher chance to fail, do it
+! * right away. Otherwise postpone it until what follows is
+! * matching and causes addstate(nextlist, ..) to be called.
+! * This is indicated by the "pim" field. */
+! {
+! nfa_pim_T *pim;
+! int cout = t->state->out1->out->c;
+!
+! /* Do it directly when what follows is possibly end of
+! * match (closing paren).
+! * Postpone when it is \@<= or \@<!, these are expensive.
+! * TODO: remove the check for t->pim and check multiple
+! * where it's used?
+! * Otherwise first do the one that has the highest chance
+! * of failing. */
+! if ((cout >= NFA_MCLOSE && cout <= NFA_MCLOSE9)
+! || (cout >= NFA_ZCLOSE && cout <= NFA_ZCLOSE9)
+! || cout == NFA_NCLOSE
+! || t->pim != NULL
+! || (t->state->c != NFA_START_INVISIBLE_BEFORE
+! && failure_chance(t->state->out1->out, 0)
+! < failure_chance(t->state->out, 0)))
+! {
+! /*
+! * First try matching the invisible match, then what
+! * follows.
+! */
+! result = recursive_regmatch(t->state, prog,
+! submatch, m, &listids);
+
+! /* 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 its out to the current
+! * list (zero-width match). */
+! addstate_here(thislist, t->state->out1->out,
+! &t->subs, t->pim, &listidx);
+! }
+! }
+! else
+! {
+! /*
+! * First try matching what follows at the current
+! * position. Only if a match is found, addstate() is
+! * called, then verify the invisible match matches.
+! * Add a nfa_pim_T to the following states, it
+! * contains info about the invisible match.
+! */
+! if (ga_grow(&pimlist, 1) == FAIL)
+! goto theend;
+! pim = (nfa_pim_T *)pimlist.ga_data + pimlist.ga_len;
+! ++pimlist.ga_len;
+! pim->state = t->state;
+! pim->pim = NULL;
+! pim->result = NFA_PIM_TODO;
+!
+! /* t->state->out1 is the corresponding END_INVISIBLE
+! * node; Add its out to the current list (zero-width
+! * match). */
+! addstate_here(thislist, t->state->out1->out, &t->subs,
+! pim, &listidx);
+! }
+ }
+ break;
+
+ case NFA_BOL:
+ if (reginput == regline)
+! addstate_here(thislist, t->state->out, &t->subs,
+! t->pim, &listidx);
+ break;
+
+ case NFA_EOL:
+ if (curc == NUL)
+! addstate_here(thislist, t->state->out, &t->subs,
+! t->pim, &listidx);
+ break;
+
+ case NFA_BOW:
+***************
+*** 4148,4154 ****
+ && vim_iswordc_buf(reginput[-1], reg_buf)))
+ bow = FALSE;
+ if (bow)
+! addstate_here(thislist, t->state->out, &t->subs, &listidx);
+ break;
+ }
+
+--- 4277,4284 ----
+ && vim_iswordc_buf(reginput[-1], reg_buf)))
+ bow = FALSE;
+ if (bow)
+! addstate_here(thislist, t->state->out, &t->subs,
+! t->pim, &listidx);
+ break;
+ }
+
+***************
+*** 4176,4194 ****
+ && 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
+--- 4306,4327 ----
+ && vim_iswordc_buf(curc, reg_buf)))
+ eow = FALSE;
+ if (eow)
+! addstate_here(thislist, t->state->out, &t->subs,
+! t->pim, &listidx);
+ break;
+ }
+
+ case NFA_BOF:
+ if (reglnum == 0 && reginput == regline
+ && (!REG_MULTI || reg_firstlnum == 1))
+! addstate_here(thislist, t->state->out, &t->subs,
+! t->pim, &listidx);
+ break;
+
+ case NFA_EOF:
+ if (reglnum == reg_maxline && curc == NUL)
+! addstate_here(thislist, t->state->out, &t->subs,
+! t->pim, &listidx);
+ break;
+
+ #ifdef FEAT_MBYTE
+***************
+*** 4277,4288 ****
+ 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;
+
+--- 4410,4425 ----
+ go_to_nextline = TRUE;
+ /* Pass -1 for the offset, which means taking the position
+ * at the start of the next line. */
+! ll = nextlist;
+! add_state = t->state->out;
+! add_off = -1;
+ }
+ else if (curc == '\n' && reg_line_lbr)
+ {
+ /* match \n as if it is an ordinary character */
+! ll = nextlist;
+! add_state = t->state->out;
+! add_off = 1;
+ }
+ break;
+
+***************
+*** 4310,4322 ****
+ /* 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;
+
+ /*
+--- 4447,4467 ----
+ /* This follows a series of negated nodes, like:
+ * CHAR(x), NFA_NOT, CHAR(y), NFA_NOT etc. */
+ if (curc > 0)
+! {
+! ll = nextlist;
+! add_state = t->state->out;
+! add_off = clen;
+! }
+ break;
+
+ case NFA_ANY:
+ /* Any char except '\0', (end of input) does not match. */
+ if (curc > 0)
+! {
+! ll = nextlist;
+! add_state = t->state->out;
+! add_off = clen;
+! }
+ break;
+
+ /*
+***************
+*** 4498,4510 ****
+ /* empty match always works, output of NFA_SKIP to be
+ * used next */
+ addstate_here(thislist, t->state->out->out, &t->subs,
+! &listidx);
+ }
+ else if (bytelen <= clen)
+ {
+ /* 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
+--- 4643,4657 ----
+ /* empty match always works, output of NFA_SKIP to be
+ * used next */
+ addstate_here(thislist, t->state->out->out, &t->subs,
+! t->pim, &listidx);
+ }
+ else if (bytelen <= clen)
+ {
+ /* match current character, jump ahead to out of
+ * NFA_SKIP */
+! ll = nextlist;
+! add_state = t->state->out->out;
+! add_off = clen;
+ #ifdef ENABLE_LOG
+ log_subsexpr(&nextlist->t[nextlist->n - 1].subs);
+ #endif
+***************
+*** 4513,4520 ****
+ {
+ /* 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
+--- 4660,4669 ----
+ {
+ /* skip ofer the matched characters, set character
+ * count in NFA_SKIP */
+! ll = nextlist;
+! add_state = t->state->out;
+! add_off = bytelen;
+! add_count = bytelen - clen;
+ #ifdef ENABLE_LOG
+ log_subsexpr(&nextlist->t[nextlist->n - 1].subs);
+ #endif
+***************
+*** 4528,4534 ****
+ 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
+--- 4677,4685 ----
+ if (t->count - clen <= 0)
+ {
+ /* end of match, go to what follows */
+! ll = nextlist;
+! add_state = t->state->out;
+! add_off = clen;
+ #ifdef ENABLE_LOG
+ log_subsexpr(&nextlist->t[nextlist->n - 1].subs);
+ #endif
+***************
+*** 4536,4543 ****
+ 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
+--- 4687,4696 ----
+ else
+ {
+ /* add state again with decremented count */
+! ll = nextlist;
+! add_state = t->state;
+! add_off = 0;
+! add_count = t->count - clen;
+ #ifdef ENABLE_LOG
+ log_subsexpr(&nextlist->t[nextlist->n - 1].subs);
+ #endif
+***************
+*** 4557,4563 ****
+ 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:
+--- 4710,4717 ----
+ 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,
+! t->pim, &listidx);
+ break;
+
+ case NFA_COL:
+***************
+*** 4566,4572 ****
+ 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:
+--- 4720,4727 ----
+ 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,
+! t->pim, &listidx);
+ break;
+
+ case NFA_VCOL:
+***************
+*** 4577,4583 ****
+ 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:
+--- 4732,4739 ----
+ reg_win == NULL ? curwin : reg_win,
+ regline, (colnr_T)(reginput - regline)) + 1);
+ if (result)
+! addstate_here(thislist, t->state->out, &t->subs,
+! t->pim, &listidx);
+ break;
+
+ case NFA_CURSOR:
+***************
+*** 4586,4592 ****
+ && ((colnr_T)(reginput - regline)
+ == reg_win->w_cursor.col));
+ if (result)
+! addstate_here(thislist, t->state->out, &t->subs, &listidx);
+ break;
+
+ default: /* regular character */
+--- 4742,4749 ----
+ && ((colnr_T)(reginput - regline)
+ == reg_win->w_cursor.col));
+ if (result)
+! addstate_here(thislist, t->state->out, &t->subs,
+! t->pim, &listidx);
+ break;
+
+ default: /* regular character */
+***************
+*** 4613,4618 ****
+--- 4770,4834 ----
+ ADD_POS_NEG_STATE(t->state);
+ break;
+ }
++
++ } /* switch (t->state->c) */
++
++ if (add_state != NULL)
++ {
++ if (t->pim != NULL)
++ {
++ /* postponed invisible match */
++ /* TODO: also do t->pim->pim recursively? */
++ if (t->pim->result == NFA_PIM_TODO)
++ {
++ #ifdef ENABLE_LOG
++ fprintf(log_fd, "\n");
++ fprintf(log_fd, "==================================\n");
++ fprintf(log_fd, "Postponed recursive nfa_regmatch()\n");
++ fprintf(log_fd, "\n");
++ #endif
++ result = recursive_regmatch(t->pim->state,
++ prog, submatch, m, &listids);
++ t->pim->result = result ? NFA_PIM_MATCH
++ : NFA_PIM_NOMATCH;
++ /* for \@! it is a match when result is FALSE */
++ if (result != t->pim->state->negated)
++ {
++ /* Copy submatch info from the recursive call */
++ copy_sub_off(&t->pim->subs.norm, &m->norm);
++ #ifdef FEAT_SYN_HL
++ copy_sub_off(&t->pim->subs.synt, &m->synt);
++ #endif
++ }
++ }
++ else
++ {
++ result = (t->pim->result == NFA_PIM_MATCH);
++ #ifdef ENABLE_LOG
++ fprintf(log_fd, "\n");
++ fprintf(log_fd, "Using previous recursive nfa_regmatch() result, result == %d\n", t->pim->result);
++ fprintf(log_fd, "MATCH = %s\n", result == TRUE ? "OK" : "FALSE");
++ fprintf(log_fd, "\n");
++ #endif
++ }
++
++ /* for \@! it is a match when result is FALSE */
++ if (result != t->pim->state->negated)
++ {
++ /* Copy submatch info from the recursive call */
++ copy_sub_off(&t->subs.norm, &t->pim->subs.norm);
++ #ifdef FEAT_SYN_HL
++ copy_sub_off(&t->subs.synt, &t->pim->subs.synt);
++ #endif
++ }
++ else
++ /* look-behind match failed, don't add the state */
++ continue;
++ }
++
++ addstate(ll, add_state, &t->subs, add_off);
++ if (add_count > 0)
++ nextlist->t[ll->n - 1].count = add_count;
+ }
+
+ } /* for (thislist = thislist; thislist->state; thislist++) */
+***************
+*** 4680,4685 ****
+--- 4896,4902 ----
+ vim_free(list[1].t);
+ vim_free(list[2].t);
+ vim_free(listids);
++ ga_clear(&pimlist);
+ #undef ADD_POS_NEG_STATE
+ #ifdef NFA_REGEXP_DEBUG_LOG
+ fclose(debug);
+*** ../vim-7.3.1109/src/version.c 2013-06-03 20:12:47.000000000 +0200
+--- src/version.c 2013-06-04 13:51:17.000000000 +0200
+***************
+*** 730,731 ****
+--- 730,733 ----
+ { /* Add new patch number below this line */
++ /**/
++ 1110,
+ /**/
+
+--
+hundred-and-one symptoms of being an internet addict:
+80. At parties, you introduce your spouse as your "service provider."
+
+ /// Bram Moolenaar -- Bram at Moolenaar.net -- http://www.Moolenaar.net \\\
+/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
+\\\ an exciting new programming language -- http://www.Zimbu.org ///
+ \\\ help me help AIDS victims -- http://ICCF-Holland.org ///
More information about the scm-commits
mailing list