@@ -4340,6 +4340,9 @@ state_in_list(
43404340 return FALSE;
43414341}
43424342
4343+ /* Offset used for "off" by addstate_here(). */
4344+ #define ADDSTATE_HERE_OFFSET 10
4345+
43434346/*
43444347 * Add "state" and possibly what follows to state list ".".
43454348 * Returns "subs_arg", possibly copied into temp_subs.
@@ -4350,9 +4353,14 @@ addstate(
43504353 nfa_state_T * state , /* state to update */
43514354 regsubs_T * subs_arg , /* pointers to subexpressions */
43524355 nfa_pim_T * pim , /* postponed look-behind match */
4353- int off ) /* byte offset, when -1 go to next line */
4356+ int off_arg ) /* byte offset, when -1 go to next line */
43544357{
43554358 int subidx ;
4359+ int off = off_arg ;
4360+ int add_here = FALSE;
4361+ int listindex = 0 ;
4362+ int k ;
4363+ int found = FALSE;
43564364 nfa_thread_T * thread ;
43574365 struct multipos save_multipos ;
43584366 int save_in_use ;
@@ -4365,6 +4373,13 @@ addstate(
43654373 int did_print = FALSE;
43664374#endif
43674375
4376+ if (off_arg <= - ADDSTATE_HERE_OFFSET )
4377+ {
4378+ add_here = TRUE;
4379+ off = 0 ;
4380+ listindex = - (off_arg + ADDSTATE_HERE_OFFSET );
4381+ }
4382+
43684383 switch (state -> c )
43694384 {
43704385 case NFA_NCLOSE :
@@ -4448,13 +4463,28 @@ addstate(
44484463 if (!nfa_has_backref && pim == NULL && !l -> has_pim
44494464 && state -> c != NFA_MATCH )
44504465 {
4466+ /* When called from addstate_here() do insert before
4467+ * existing states. */
4468+ if (add_here )
4469+ {
4470+ for (k = 0 ; k < l -> n && k < listindex ; ++ k )
4471+ if (l -> t [k ].state -> id == state -> id )
4472+ {
4473+ found = TRUE;
4474+ break ;
4475+ }
4476+ }
4477+ if (!add_here || found )
4478+ {
44514479skip_add :
44524480#ifdef ENABLE_LOG
4453- nfa_set_code (state -> c );
4454- fprintf (log_fd , "> Not adding state %d to list %d. char %d: %s\n" ,
4455- abs (state -> id ), l -> id , state -> c , code );
4481+ nfa_set_code (state -> c );
4482+ fprintf (log_fd , "> Not adding state %d to list %d. char %d: %s pim: %s has_pim: %d found: %d\n" ,
4483+ abs (state -> id ), l -> id , state -> c , code ,
4484+ pim == NULL ? "NULL" : "yes" , l -> has_pim , found );
44564485#endif
4457- return subs ;
4486+ return subs ;
4487+ }
44584488 }
44594489
44604490 /* Do not add the state again when it exists with the same
@@ -4519,14 +4549,14 @@ addstate(
45194549
45204550 case NFA_SPLIT :
45214551 /* order matters here */
4522- subs = addstate (l , state -> out , subs , pim , off );
4523- subs = addstate (l , state -> out1 , subs , pim , off );
4552+ subs = addstate (l , state -> out , subs , pim , off_arg );
4553+ subs = addstate (l , state -> out1 , subs , pim , off_arg );
45244554 break ;
45254555
45264556 case NFA_EMPTY :
45274557 case NFA_NOPEN :
45284558 case NFA_NCLOSE :
4529- subs = addstate (l , state -> out , subs , pim , off );
4559+ subs = addstate (l , state -> out , subs , pim , off_arg );
45304560 break ;
45314561
45324562 case NFA_MOPEN :
@@ -4626,7 +4656,7 @@ addstate(
46264656 sub -> list .line [subidx ].start = reginput + off ;
46274657 }
46284658
4629- subs = addstate (l , state -> out , subs , pim , off );
4659+ subs = addstate (l , state -> out , subs , pim , off_arg );
46304660 /* "subs" may have changed, need to set "sub" again */
46314661#ifdef FEAT_SYN_HL
46324662 if (state -> c >= NFA_ZOPEN && state -> c <= NFA_ZOPEN9 )
@@ -4652,7 +4682,7 @@ addstate(
46524682 : subs -> norm .list .line [0 ].end != NULL ))
46534683 {
46544684 /* Do not overwrite the position set by \ze. */
4655- subs = addstate (l , state -> out , subs , pim , off );
4685+ subs = addstate (l , state -> out , subs , pim , off_arg );
46564686 break ;
46574687 }
46584688 case NFA_MCLOSE1 :
@@ -4725,7 +4755,7 @@ addstate(
47254755 vim_memset (& save_multipos , 0 , sizeof (save_multipos ));
47264756 }
47274757
4728- subs = addstate (l , state -> out , subs , pim , off );
4758+ subs = addstate (l , state -> out , subs , pim , off_arg );
47294759 /* "subs" may have changed, need to set "sub" again */
47304760#ifdef FEAT_SYN_HL
47314761 if (state -> c >= NFA_ZCLOSE && state -> c <= NFA_ZCLOSE9 )
@@ -4762,8 +4792,10 @@ addstate_here(
47624792 int count ;
47634793 int listidx = * ip ;
47644794
4765- /* first add the state(s) at the end, so that we know how many there are */
4766- addstate (l , state , subs , pim , 0 );
4795+ /* First add the state(s) at the end, so that we know how many there are.
4796+ * Pass the listidx as offset (avoids adding another argument to
4797+ * addstate(). */
4798+ addstate (l , state , subs , pim , - listidx - ADDSTATE_HERE_OFFSET );
47674799
47684800 /* when "*ip" was at the end of the list, nothing to do */
47694801 if (listidx + 1 == tlen )
0 commit comments