To: vim_dev@googlegroups.com Subject: Patch 7.4a.032 Fcc: outbox From: Bram Moolenaar 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 -- 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 ///