@@ -3535,7 +3535,8 @@ static void copy_sub __ARGS((regsub_T *to, regsub_T *from));
35353535static void copy_sub_off __ARGS ((regsub_T * to , regsub_T * from ));
35363536static int sub_equal __ARGS ((regsub_T * sub1 , regsub_T * sub2 ));
35373537static int match_backref __ARGS ((regsub_T * sub , int subidx , int * bytelen ));
3538- static int has_state_with_pos __ARGS ((nfa_list_T * l , nfa_state_T * state , regsubs_T * subs ));
3538+ static int has_state_with_pos __ARGS ((nfa_list_T * l , nfa_state_T * state , regsubs_T * subs , nfa_pim_T * pim ));
3539+ static int pim_equal __ARGS ((nfa_pim_T * one , nfa_pim_T * two ));
35393540static int state_in_list __ARGS ((nfa_list_T * l , nfa_state_T * state , regsubs_T * subs ));
35403541static regsubs_T * addstate __ARGS ((nfa_list_T * l , nfa_state_T * state , regsubs_T * subs_arg , nfa_pim_T * pim , int off ));
35413542static void addstate_here __ARGS ((nfa_list_T * l , nfa_state_T * state , regsubs_T * subs , nfa_pim_T * pim , int * ip ));
@@ -3701,10 +3702,11 @@ report_state(char *action,
37013702 * positions as "subs".
37023703 */
37033704 static int
3704- has_state_with_pos (l , state , subs )
3705+ has_state_with_pos (l , state , subs , pim )
37053706 nfa_list_T * l ; /* runtime state list */
37063707 nfa_state_T * state ; /* state to update */
37073708 regsubs_T * subs ; /* pointers to subexpressions */
3709+ nfa_pim_T * pim ; /* postponed match or NULL */
37083710{
37093711 nfa_thread_T * thread ;
37103712 int i ;
@@ -3718,12 +3720,37 @@ has_state_with_pos(l, state, subs)
37183720 && (!nfa_has_zsubexpr
37193721 || sub_equal (& thread -> subs .synt , & subs -> synt ))
37203722#endif
3721- )
3723+ && pim_equal ( & thread -> pim , pim ) )
37223724 return TRUE;
37233725 }
37243726 return FALSE;
37253727}
37263728
3729+ /*
3730+ * Return TRUE if "one" and "two" are equal. That includes when both are not
3731+ * set.
3732+ */
3733+ static int
3734+ pim_equal (one , two )
3735+ nfa_pim_T * one ;
3736+ nfa_pim_T * two ;
3737+ {
3738+ int one_unused = (one == NULL || one -> result == NFA_PIM_UNUSED );
3739+ int two_unused = (two == NULL || two -> result == NFA_PIM_UNUSED );
3740+
3741+ if (one_unused )
3742+ /* one is unused: equal when two is also unused */
3743+ return two_unused ;
3744+ if (two_unused )
3745+ /* one is used and two is not: not equal */
3746+ return FALSE;
3747+ /* compare the position */
3748+ if (REG_MULTI )
3749+ return one -> end .pos .lnum == two -> end .pos .lnum
3750+ && one -> end .pos .col == two -> end .pos .col ;
3751+ return one -> end .ptr == two -> end .ptr ;
3752+ }
3753+
37273754/*
37283755 * Return TRUE if "state" leads to a NFA_MATCH without advancing the input.
37293756 */
@@ -3825,7 +3852,7 @@ state_in_list(l, state, subs)
38253852{
38263853 if (state -> lastlist [nfa_ll_index ] == l -> id )
38273854 {
3828- if (!nfa_has_backref || has_state_with_pos (l , state , subs ))
3855+ if (!nfa_has_backref || has_state_with_pos (l , state , subs , NULL ))
38293856 return TRUE;
38303857 }
38313858 return FALSE;
@@ -3952,7 +3979,7 @@ addstate(l, state, subs_arg, pim, off)
39523979
39533980 /* Do not add the state again when it exists with the same
39543981 * positions. */
3955- if (has_state_with_pos (l , state , subs ))
3982+ if (has_state_with_pos (l , state , subs , pim ))
39563983 goto skip_add ;
39573984 }
39583985
0 commit comments