To:
[email protected]
Subject: Patch 7.4a.032
Fcc: outbox
From: Bram Moolenaar <
[email protected]>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------------
Patch 7.4a.032
Problem: New regexp engine: Does not match shorter alternative. (Ingo
Karkat)
Solution: Do not drop a new state when the PIM info is different.
Files: src/regexp_nfa.c
*** ../vim-7.4a.031/src/regexp_nfa.c 2013-07-17 19:22:04.000000000 +0200
--- src/regexp_nfa.c 2013-07-17 20:51:06.000000000 +0200
***************
*** 3535,3541 ****
static void copy_sub_off __ARGS((regsub_T *to, regsub_T *from));
static int sub_equal __ARGS((regsub_T *sub1, regsub_T *sub2));
static int match_backref __ARGS((regsub_T *sub, int subidx, int *bytelen));
! static int has_state_with_pos __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs));
static int state_in_list __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs));
static regsubs_T *addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs_arg, nfa_pim_T *pim, int off));
static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, nfa_pim_T *pim, int *ip));
--- 3535,3542 ----
static void copy_sub_off __ARGS((regsub_T *to, regsub_T *from));
static int sub_equal __ARGS((regsub_T *sub1, regsub_T *sub2));
static int match_backref __ARGS((regsub_T *sub, int subidx, int *bytelen));
! static int has_state_with_pos __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, nfa_pim_T *pim));
! static int pim_equal __ARGS((nfa_pim_T *one, nfa_pim_T *two));
static int state_in_list __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs));
static regsubs_T *addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs_arg, nfa_pim_T *pim, int off));
static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, nfa_pim_T *pim, int *ip));
***************
*** 3701,3710 ****
* positions as "subs".
*/
static int
! has_state_with_pos(l, state, subs)
nfa_list_T *l; /* runtime state list */
nfa_state_T *state; /* state to update */
regsubs_T *subs; /* pointers to subexpressions */
{
nfa_thread_T *thread;
int i;
--- 3702,3712 ----
* positions as "subs".
*/
static int
! has_state_with_pos(l, state, subs, pim)
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 match or NULL */
{
nfa_thread_T *thread;
int i;
***************
*** 3718,3730 ****
&& (!nfa_has_zsubexpr
|| sub_equal(&thread->subs.synt, &subs->synt))
#endif
! )
return TRUE;
}
return FALSE;
}
/*
* Return TRUE if "state" leads to a NFA_MATCH without advancing the input.
*/
static int
--- 3720,3757 ----
&& (!nfa_has_zsubexpr
|| sub_equal(&thread->subs.synt, &subs->synt))
#endif
! && pim_equal(&thread->pim, pim))
return TRUE;
}
return FALSE;
}
/*
+ * Return TRUE if "one" and "two" are equal. That includes when both are not
+ * set.
+ */
+ static int
+ pim_equal(one, two)
+ nfa_pim_T *one;
+ nfa_pim_T *two;
+ {
+ int one_unused = (one == NULL || one->result == NFA_PIM_UNUSED);
+ int two_unused = (two == NULL || two->result == NFA_PIM_UNUSED);
+
+ if (one_unused)
+ /* one is unused: equal when two is also unused */
+ return two_unused;
+ if (two_unused)
+ /* one is used and two is not: not equal */
+ return FALSE;
+ /* compare the position */
+ if (REG_MULTI)
+ return one->end.pos.lnum == two->end.pos.lnum
+ && one->end.pos.col == two->end.pos.col;
+ return one->end.ptr == two->end.ptr;
+ }
+
+ /*
* Return TRUE if "state" leads to a NFA_MATCH without advancing the input.
*/
static int
***************
*** 3825,3831 ****
{
if (state->lastlist[nfa_ll_index] == l->id)
{
! if (!nfa_has_backref || has_state_with_pos(l, state, subs))
return TRUE;
}
return FALSE;
--- 3852,3858 ----
{
if (state->lastlist[nfa_ll_index] == l->id)
{
! if (!nfa_has_backref || has_state_with_pos(l, state, subs, NULL))
return TRUE;
}
return FALSE;
***************
*** 3952,3958 ****
/* Do not add the state again when it exists with the same
* positions. */
! if (has_state_with_pos(l, state, subs))
goto skip_add;
}
--- 3979,3985 ----
/* Do not add the state again when it exists with the same
* positions. */
! if (has_state_with_pos(l, state, subs, pim))
goto skip_add;
}
*** ../vim-7.4a.031/src/version.c 2013-07-17 19:22:04.000000000 +0200
--- src/version.c 2013-07-17 21:08:03.000000000 +0200
***************
*** 729,730 ****
--- 729,732 ----
{ /* Add new patch number below this line */
+ /**/
+ 32,
/**/
--
It doesn't really matter what you are able to do if you don't do it.
(Bram Moolenaar)
/// Bram Moolenaar --
[email protected] --
http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language --
http://www.Zimbu.org ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///