Karsten Hopp c7dad5
To: vim_dev@googlegroups.com
Karsten Hopp c7dad5
Subject: Patch 7.3.1033
Karsten Hopp c7dad5
Fcc: outbox
Karsten Hopp c7dad5
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp c7dad5
Mime-Version: 1.0
Karsten Hopp c7dad5
Content-Type: text/plain; charset=UTF-8
Karsten Hopp c7dad5
Content-Transfer-Encoding: 8bit
Karsten Hopp c7dad5
------------
Karsten Hopp c7dad5
Karsten Hopp c7dad5
Patch 7.3.1033
Karsten Hopp c7dad5
Problem:    "\1" .. "\9" are not supported in the new regexp engine.
Karsten Hopp c7dad5
Solution:   Implement them.  Add a few more tests.
Karsten Hopp c7dad5
Files:	    src/regexp_nfa.c, src/testdir/test64.in, src/testdir/test64.ok,
Karsten Hopp c7dad5
	    src/regexp.h
Karsten Hopp c7dad5
Karsten Hopp c7dad5
Karsten Hopp c7dad5
*** ../vim-7.3.1032/src/regexp_nfa.c	2013-05-27 20:10:40.000000000 +0200
Karsten Hopp c7dad5
--- src/regexp_nfa.c	2013-05-28 21:57:24.000000000 +0200
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 73,78 ****
Karsten Hopp c7dad5
--- 73,89 ----
Karsten Hopp c7dad5
      NFA_PREV_ATOM_JUST_BEFORE_NEG,  /* Used for \@
Karsten Hopp c7dad5
      NFA_PREV_ATOM_LIKE_PATTERN,	    /* Used for \@> */
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
+     NFA_BACKREF1,		    /* \1 */
Karsten Hopp c7dad5
+     NFA_BACKREF2,		    /* \2 */
Karsten Hopp c7dad5
+     NFA_BACKREF3,		    /* \3 */
Karsten Hopp c7dad5
+     NFA_BACKREF4,		    /* \4 */
Karsten Hopp c7dad5
+     NFA_BACKREF5,		    /* \5 */
Karsten Hopp c7dad5
+     NFA_BACKREF6,		    /* \6 */
Karsten Hopp c7dad5
+     NFA_BACKREF7,		    /* \7 */
Karsten Hopp c7dad5
+     NFA_BACKREF8,		    /* \8 */
Karsten Hopp c7dad5
+     NFA_BACKREF9,		    /* \9 */
Karsten Hopp c7dad5
+     NFA_SKIP,			    /* Skip characters */
Karsten Hopp c7dad5
+ 
Karsten Hopp c7dad5
      NFA_MOPEN,
Karsten Hopp c7dad5
      NFA_MCLOSE = NFA_MOPEN + NSUBEXP,
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 709,715 ****
Karsten Hopp c7dad5
  	    p = vim_strchr(classchars, no_Magic(c));
Karsten Hopp c7dad5
  	    if (p == NULL)
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
! 		return FAIL;	    /* runtime error */
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  #ifdef FEAT_MBYTE
Karsten Hopp c7dad5
  	    /* When '.' is followed by a composing char ignore the dot, so that
Karsten Hopp c7dad5
--- 720,727 ----
Karsten Hopp c7dad5
  	    p = vim_strchr(classchars, no_Magic(c));
Karsten Hopp c7dad5
  	    if (p == NULL)
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
! 		EMSGN("INTERNAL: Unknown character class char: %ld", c);
Karsten Hopp c7dad5
! 		return FAIL;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  #ifdef FEAT_MBYTE
Karsten Hopp c7dad5
  	    /* When '.' is followed by a composing char ignore the dot, so that
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 766,785 ****
Karsten Hopp c7dad5
  	    return FAIL;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	case Magic('~'):		/* previous substitute pattern */
Karsten Hopp c7dad5
! 	    /* Not supported yet */
Karsten Hopp c7dad5
  	    return FAIL;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
! 	case Magic('1'):
Karsten Hopp c7dad5
! 	case Magic('2'):
Karsten Hopp c7dad5
! 	case Magic('3'):
Karsten Hopp c7dad5
! 	case Magic('4'):
Karsten Hopp c7dad5
! 	case Magic('5'):
Karsten Hopp c7dad5
! 	case Magic('6'):
Karsten Hopp c7dad5
! 	case Magic('7'):
Karsten Hopp c7dad5
! 	case Magic('8'):
Karsten Hopp c7dad5
! 	case Magic('9'):
Karsten Hopp c7dad5
! 	    /* not supported yet */
Karsten Hopp c7dad5
! 	    return FAIL;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	case Magic('z'):
Karsten Hopp c7dad5
  	    c = no_Magic(getchr());
Karsten Hopp c7dad5
--- 778,795 ----
Karsten Hopp c7dad5
  	    return FAIL;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	case Magic('~'):		/* previous substitute pattern */
Karsten Hopp c7dad5
! 	    /* TODO: Not supported yet */
Karsten Hopp c7dad5
  	    return FAIL;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
! 	case Magic('1'): EMIT(NFA_BACKREF1); break;
Karsten Hopp c7dad5
! 	case Magic('2'): EMIT(NFA_BACKREF2); break;
Karsten Hopp c7dad5
! 	case Magic('3'): EMIT(NFA_BACKREF3); break;
Karsten Hopp c7dad5
! 	case Magic('4'): EMIT(NFA_BACKREF4); break;
Karsten Hopp c7dad5
! 	case Magic('5'): EMIT(NFA_BACKREF5); break;
Karsten Hopp c7dad5
! 	case Magic('6'): EMIT(NFA_BACKREF6); break;
Karsten Hopp c7dad5
! 	case Magic('7'): EMIT(NFA_BACKREF7); break;
Karsten Hopp c7dad5
! 	case Magic('8'): EMIT(NFA_BACKREF8); break;
Karsten Hopp c7dad5
! 	case Magic('9'): EMIT(NFA_BACKREF9); break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	case Magic('z'):
Karsten Hopp c7dad5
  	    c = no_Magic(getchr());
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 802,808 ****
Karsten Hopp c7dad5
  		case '8':
Karsten Hopp c7dad5
  		case '9':
Karsten Hopp c7dad5
  		case '(':
Karsten Hopp c7dad5
! 		    /* \z1...\z9 and \z( not yet supported */
Karsten Hopp c7dad5
  		    return FAIL;
Karsten Hopp c7dad5
  		default:
Karsten Hopp c7dad5
  		    syntax_error = TRUE;
Karsten Hopp c7dad5
--- 812,818 ----
Karsten Hopp c7dad5
  		case '8':
Karsten Hopp c7dad5
  		case '9':
Karsten Hopp c7dad5
  		case '(':
Karsten Hopp c7dad5
! 		    /* TODO: \z1...\z9 and \z( not yet supported */
Karsten Hopp c7dad5
  		    return FAIL;
Karsten Hopp c7dad5
  		default:
Karsten Hopp c7dad5
  		    syntax_error = TRUE;
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 854,885 ****
Karsten Hopp c7dad5
  		 * pattern -- regardless of whether or not it makes sense. */
Karsten Hopp c7dad5
  		case '^':
Karsten Hopp c7dad5
  		    EMIT(NFA_BOF);
Karsten Hopp c7dad5
! 		    /* Not yet supported */
Karsten Hopp c7dad5
  		    return FAIL;
Karsten Hopp c7dad5
  		    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  		case '$':
Karsten Hopp c7dad5
  		    EMIT(NFA_EOF);
Karsten Hopp c7dad5
! 		    /* Not yet supported */
Karsten Hopp c7dad5
  		    return FAIL;
Karsten Hopp c7dad5
  		    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  		case '#':
Karsten Hopp c7dad5
! 		    /* not supported yet */
Karsten Hopp c7dad5
  		    return FAIL;
Karsten Hopp c7dad5
  		    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  		case 'V':
Karsten Hopp c7dad5
! 		    /* not supported yet */
Karsten Hopp c7dad5
  		    return FAIL;
Karsten Hopp c7dad5
  		    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  		case '[':
Karsten Hopp c7dad5
! 		    /* \%[abc] not supported yet */
Karsten Hopp c7dad5
  		    return FAIL;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  		default:
Karsten Hopp c7dad5
! 		    /* not supported yet */
Karsten Hopp c7dad5
  		    return FAIL;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
--- 864,913 ----
Karsten Hopp c7dad5
  		 * pattern -- regardless of whether or not it makes sense. */
Karsten Hopp c7dad5
  		case '^':
Karsten Hopp c7dad5
  		    EMIT(NFA_BOF);
Karsten Hopp c7dad5
! 		    /* TODO: Not yet supported */
Karsten Hopp c7dad5
  		    return FAIL;
Karsten Hopp c7dad5
  		    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  		case '$':
Karsten Hopp c7dad5
  		    EMIT(NFA_EOF);
Karsten Hopp c7dad5
! 		    /* TODO: Not yet supported */
Karsten Hopp c7dad5
  		    return FAIL;
Karsten Hopp c7dad5
  		    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  		case '#':
Karsten Hopp c7dad5
! 		    /* TODO: not supported yet */
Karsten Hopp c7dad5
  		    return FAIL;
Karsten Hopp c7dad5
  		    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  		case 'V':
Karsten Hopp c7dad5
! 		    /* TODO: not supported yet */
Karsten Hopp c7dad5
  		    return FAIL;
Karsten Hopp c7dad5
  		    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  		case '[':
Karsten Hopp c7dad5
! 		    /* TODO: \%[abc] not supported yet */
Karsten Hopp c7dad5
! 		    return FAIL;
Karsten Hopp c7dad5
! 
Karsten Hopp c7dad5
! 		case '0':
Karsten Hopp c7dad5
! 		case '1':
Karsten Hopp c7dad5
! 		case '2':
Karsten Hopp c7dad5
! 		case '3':
Karsten Hopp c7dad5
! 		case '4':
Karsten Hopp c7dad5
! 		case '5':
Karsten Hopp c7dad5
! 		case '6':
Karsten Hopp c7dad5
! 		case '7':
Karsten Hopp c7dad5
! 		case '8':
Karsten Hopp c7dad5
! 		case '9':
Karsten Hopp c7dad5
! 		case '<':
Karsten Hopp c7dad5
! 		case '>':
Karsten Hopp c7dad5
! 		case '\'':
Karsten Hopp c7dad5
! 		    /* TODO: not supported yet */
Karsten Hopp c7dad5
  		    return FAIL;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  		default:
Karsten Hopp c7dad5
! 		    syntax_error = TRUE;
Karsten Hopp c7dad5
! 		    EMSGN(_("E867: (NFA) Unknown operator '\\%%%c'"),
Karsten Hopp c7dad5
! 								 no_Magic(c));
Karsten Hopp c7dad5
  		    return FAIL;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 1672,1677 ****
Karsten Hopp c7dad5
--- 1700,1716 ----
Karsten Hopp c7dad5
  	case NFA_ZSTART:    STRCPY(code, "NFA_ZSTART"); break;
Karsten Hopp c7dad5
  	case NFA_ZEND:	    STRCPY(code, "NFA_ZEND"); break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
+ 	case NFA_BACKREF1:  STRCPY(code, "NFA_BACKREF1"); break;
Karsten Hopp c7dad5
+ 	case NFA_BACKREF2:  STRCPY(code, "NFA_BACKREF2"); break;
Karsten Hopp c7dad5
+ 	case NFA_BACKREF3:  STRCPY(code, "NFA_BACKREF3"); break;
Karsten Hopp c7dad5
+ 	case NFA_BACKREF4:  STRCPY(code, "NFA_BACKREF4"); break;
Karsten Hopp c7dad5
+ 	case NFA_BACKREF5:  STRCPY(code, "NFA_BACKREF5"); break;
Karsten Hopp c7dad5
+ 	case NFA_BACKREF6:  STRCPY(code, "NFA_BACKREF6"); break;
Karsten Hopp c7dad5
+ 	case NFA_BACKREF7:  STRCPY(code, "NFA_BACKREF7"); break;
Karsten Hopp c7dad5
+ 	case NFA_BACKREF8:  STRCPY(code, "NFA_BACKREF8"); break;
Karsten Hopp c7dad5
+ 	case NFA_BACKREF9:  STRCPY(code, "NFA_BACKREF9"); break;
Karsten Hopp c7dad5
+ 	case NFA_SKIP:	    STRCPY(code, "NFA_SKIP"); break;
Karsten Hopp c7dad5
+ 
Karsten Hopp c7dad5
  	case NFA_PREV_ATOM_NO_WIDTH:
Karsten Hopp c7dad5
  			    STRCPY(code, "NFA_PREV_ATOM_NO_WIDTH"); break;
Karsten Hopp c7dad5
  	case NFA_NOPEN:		    STRCPY(code, "NFA_MOPEN_INVISIBLE"); break;
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 1949,1955 ****
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
      s->id   = istate;
Karsten Hopp c7dad5
      s->lastlist = 0;
Karsten Hopp c7dad5
-     s->visits = 0;
Karsten Hopp c7dad5
      s->negated = FALSE;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
      return s;
Karsten Hopp c7dad5
--- 1988,1993 ----
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 2416,2421 ****
Karsten Hopp c7dad5
--- 2454,2483 ----
Karsten Hopp c7dad5
  	    PUSH(frag(s, list1(&s1->out)));
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
+ 	case NFA_BACKREF1:
Karsten Hopp c7dad5
+ 	case NFA_BACKREF2:
Karsten Hopp c7dad5
+ 	case NFA_BACKREF3:
Karsten Hopp c7dad5
+ 	case NFA_BACKREF4:
Karsten Hopp c7dad5
+ 	case NFA_BACKREF5:
Karsten Hopp c7dad5
+ 	case NFA_BACKREF6:
Karsten Hopp c7dad5
+ 	case NFA_BACKREF7:
Karsten Hopp c7dad5
+ 	case NFA_BACKREF8:
Karsten Hopp c7dad5
+ 	case NFA_BACKREF9:
Karsten Hopp c7dad5
+ 	    if (nfa_calc_size == TRUE)
Karsten Hopp c7dad5
+ 	    {
Karsten Hopp c7dad5
+ 		nstate += 2;
Karsten Hopp c7dad5
+ 		break;
Karsten Hopp c7dad5
+ 	    }
Karsten Hopp c7dad5
+ 	    s = new_state(*p, NULL, NULL);
Karsten Hopp c7dad5
+ 	    if (s == NULL)
Karsten Hopp c7dad5
+ 		goto theend;
Karsten Hopp c7dad5
+ 	    s1 = new_state(NFA_SKIP, NULL, NULL);
Karsten Hopp c7dad5
+ 	    if (s1 == NULL)
Karsten Hopp c7dad5
+ 		goto theend;
Karsten Hopp c7dad5
+ 	    patch(list1(&s->out), s1);
Karsten Hopp c7dad5
+ 	    PUSH(frag(s, list1(&s1->out)));
Karsten Hopp c7dad5
+ 	    break;
Karsten Hopp c7dad5
+ 
Karsten Hopp c7dad5
  	case NFA_ZSTART:
Karsten Hopp c7dad5
  	case NFA_ZEND:
Karsten Hopp c7dad5
  	default:
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 2495,2523 ****
Karsten Hopp c7dad5
  typedef struct
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
      nfa_state_T	*state;
Karsten Hopp c7dad5
      regsub_T	sub;		/* submatch info, only party used */
Karsten Hopp c7dad5
  } nfa_thread_T;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  /* nfa_list_T contains the alternative NFA execution states. */
Karsten Hopp c7dad5
  typedef struct
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
!     nfa_thread_T    *t;
Karsten Hopp c7dad5
!     int		    n;
Karsten Hopp c7dad5
  } nfa_list_T;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  /* Used during execution: whether a match has been found. */
Karsten Hopp c7dad5
  static int nfa_match;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
! static void addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsub_T *m, int off, int lid));
Karsten Hopp c7dad5
! static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state, regsub_T *m, int lid, int *ip));
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
      static void
Karsten Hopp c7dad5
! addstate(l, state, m, off, lid)
Karsten Hopp c7dad5
      nfa_list_T		*l;	/* runtime state list */
Karsten Hopp c7dad5
      nfa_state_T		*state;	/* state to update */
Karsten Hopp c7dad5
!     regsub_T		*m;	/* pointers to subexpressions */
Karsten Hopp c7dad5
      int			off;	/* byte offset, when -1 go to next line */
Karsten Hopp c7dad5
-     int			lid;
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
      int			subidx;
Karsten Hopp c7dad5
      nfa_thread_T	*lastthread;
Karsten Hopp c7dad5
--- 2557,2610 ----
Karsten Hopp c7dad5
  typedef struct
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
      nfa_state_T	*state;
Karsten Hopp c7dad5
+     int		count;
Karsten Hopp c7dad5
      regsub_T	sub;		/* submatch info, only party used */
Karsten Hopp c7dad5
  } nfa_thread_T;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  /* nfa_list_T contains the alternative NFA execution states. */
Karsten Hopp c7dad5
  typedef struct
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
!     nfa_thread_T    *t;		/* allocated array of states */
Karsten Hopp c7dad5
!     int		    n;		/* nr of states in "t" */
Karsten Hopp c7dad5
!     int		    id;		/* ID of the list */
Karsten Hopp c7dad5
  } nfa_list_T;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
+ #ifdef ENABLE_LOG
Karsten Hopp c7dad5
+     static void
Karsten Hopp c7dad5
+ log_subexpr(sub)
Karsten Hopp c7dad5
+     regsub_T *sub;
Karsten Hopp c7dad5
+ {
Karsten Hopp c7dad5
+     int j;
Karsten Hopp c7dad5
+ 
Karsten Hopp c7dad5
+     for (j = 0; j < sub->in_use; j++)
Karsten Hopp c7dad5
+ 	if (REG_MULTI)
Karsten Hopp c7dad5
+ 	    fprintf(log_fd, "\n *** group %d, start: c=%d, l=%d, end: c=%d, l=%d",
Karsten Hopp c7dad5
+ 		    j,
Karsten Hopp c7dad5
+ 		    sub->multilist[j].start.col,
Karsten Hopp c7dad5
+ 		    (int)sub->multilist[j].start.lnum,
Karsten Hopp c7dad5
+ 		    sub->multilist[j].end.col,
Karsten Hopp c7dad5
+ 		    (int)sub->multilist[j].end.lnum);
Karsten Hopp c7dad5
+ 	else
Karsten Hopp c7dad5
+ 	    fprintf(log_fd, "\n *** group %d, start: \"%s\", end: \"%s\"",
Karsten Hopp c7dad5
+ 		    j,
Karsten Hopp c7dad5
+ 		    (char *)sub->linelist[j].start,
Karsten Hopp c7dad5
+ 		    (char *)sub->linelist[j].end);
Karsten Hopp c7dad5
+     fprintf(log_fd, "\n");
Karsten Hopp c7dad5
+ }
Karsten Hopp c7dad5
+ #endif
Karsten Hopp c7dad5
+ 
Karsten Hopp c7dad5
  /* Used during execution: whether a match has been found. */
Karsten Hopp c7dad5
  static int nfa_match;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
! static void addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsub_T *sub, int off));
Karsten Hopp c7dad5
! static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state, regsub_T *sub, int *ip));
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
      static void
Karsten Hopp c7dad5
! addstate(l, state, sub, off)
Karsten Hopp c7dad5
      nfa_list_T		*l;	/* runtime state list */
Karsten Hopp c7dad5
      nfa_state_T		*state;	/* state to update */
Karsten Hopp c7dad5
!     regsub_T		*sub;	/* pointers to subexpressions */
Karsten Hopp c7dad5
      int			off;	/* byte offset, when -1 go to next line */
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
      int			subidx;
Karsten Hopp c7dad5
      nfa_thread_T	*lastthread;
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 2545,2585 ****
Karsten Hopp c7dad5
  	case NFA_MCLOSE + 7:
Karsten Hopp c7dad5
  	case NFA_MCLOSE + 8:
Karsten Hopp c7dad5
  	case NFA_MCLOSE + 9:
Karsten Hopp c7dad5
! 	    /* Do not remember these nodes in list "thislist" or "nextlist" */
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	default:
Karsten Hopp c7dad5
! 	    if (state->lastlist == lid)
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
! 		if (++state->visits > 2)
Karsten Hopp c7dad5
! 		    return;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
! 	    else
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
! 		/* add the state to the list */
Karsten Hopp c7dad5
! 		state->lastlist = lid;
Karsten Hopp c7dad5
! 		lastthread = &l->t[l->n++];
Karsten Hopp c7dad5
! 		lastthread->state = state;
Karsten Hopp c7dad5
! 		lastthread->sub.in_use = m->in_use;
Karsten Hopp c7dad5
! 		if (m->in_use > 0)
Karsten Hopp c7dad5
! 		{
Karsten Hopp c7dad5
! 		    /* Copy the match start and end positions. */
Karsten Hopp c7dad5
! 		    if (REG_MULTI)
Karsten Hopp c7dad5
! 			mch_memmove(&lastthread->sub.multilist[0],
Karsten Hopp c7dad5
! 				    &m->multilist[0],
Karsten Hopp c7dad5
! 				    sizeof(struct multipos) * m->in_use);
Karsten Hopp c7dad5
! 		    else
Karsten Hopp c7dad5
! 			mch_memmove(&lastthread->sub.linelist[0],
Karsten Hopp c7dad5
! 				    &m->linelist[0],
Karsten Hopp c7dad5
! 				    sizeof(struct linepos) * m->in_use);
Karsten Hopp c7dad5
! 		}
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
      }
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  #ifdef ENABLE_LOG
Karsten Hopp c7dad5
      nfa_set_code(state->c);
Karsten Hopp c7dad5
!     fprintf(log_fd, "> Adding state %d to list. Character %s, code %d\n",
Karsten Hopp c7dad5
! 	abs(state->id), code, state->c);
Karsten Hopp c7dad5
  #endif
Karsten Hopp c7dad5
      switch (state->c)
Karsten Hopp c7dad5
      {
Karsten Hopp c7dad5
--- 2632,2689 ----
Karsten Hopp c7dad5
  	case NFA_MCLOSE + 7:
Karsten Hopp c7dad5
  	case NFA_MCLOSE + 8:
Karsten Hopp c7dad5
  	case NFA_MCLOSE + 9:
Karsten Hopp c7dad5
! 	    /* These nodes are not added themselves but their "out" and/or
Karsten Hopp c7dad5
! 	     * "out1" may be added below.  */
Karsten Hopp c7dad5
! 	    break;
Karsten Hopp c7dad5
! 
Karsten Hopp c7dad5
! 	case NFA_MOPEN:
Karsten Hopp c7dad5
! 	case NFA_MOPEN + 1:
Karsten Hopp c7dad5
! 	case NFA_MOPEN + 2:
Karsten Hopp c7dad5
! 	case NFA_MOPEN + 3:
Karsten Hopp c7dad5
! 	case NFA_MOPEN + 4:
Karsten Hopp c7dad5
! 	case NFA_MOPEN + 5:
Karsten Hopp c7dad5
! 	case NFA_MOPEN + 6:
Karsten Hopp c7dad5
! 	case NFA_MOPEN + 7:
Karsten Hopp c7dad5
! 	case NFA_MOPEN + 8:
Karsten Hopp c7dad5
! 	case NFA_MOPEN + 9:
Karsten Hopp c7dad5
! 	    /* These nodes do not need to be added, but we need to bail out
Karsten Hopp c7dad5
! 	     * when it was tried to be added to this list before. */
Karsten Hopp c7dad5
! 	    if (state->lastlist == l->id)
Karsten Hopp c7dad5
! 		return;
Karsten Hopp c7dad5
! 	    state->lastlist = l->id;
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	default:
Karsten Hopp c7dad5
! 	    if (state->lastlist == l->id)
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
! 		/* This state is already in the list, don't add it again,
Karsten Hopp c7dad5
! 		 * unless it is an MOPEN that is used for a backreference. */
Karsten Hopp c7dad5
! 		return;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
! 
Karsten Hopp c7dad5
! 	    /* add the state to the list */
Karsten Hopp c7dad5
! 	    state->lastlist = l->id;
Karsten Hopp c7dad5
! 	    lastthread = &l->t[l->n++];
Karsten Hopp c7dad5
! 	    lastthread->state = state;
Karsten Hopp c7dad5
! 	    lastthread->sub.in_use = sub->in_use;
Karsten Hopp c7dad5
! 	    if (sub->in_use > 0)
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
! 		/* Copy the match start and end positions. */
Karsten Hopp c7dad5
! 		if (REG_MULTI)
Karsten Hopp c7dad5
! 		    mch_memmove(&lastthread->sub.multilist[0],
Karsten Hopp c7dad5
! 				&sub->multilist[0],
Karsten Hopp c7dad5
! 				sizeof(struct multipos) * sub->in_use);
Karsten Hopp c7dad5
! 		else
Karsten Hopp c7dad5
! 		    mch_memmove(&lastthread->sub.linelist[0],
Karsten Hopp c7dad5
! 				&sub->linelist[0],
Karsten Hopp c7dad5
! 				sizeof(struct linepos) * sub->in_use);
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
      }
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  #ifdef ENABLE_LOG
Karsten Hopp c7dad5
      nfa_set_code(state->c);
Karsten Hopp c7dad5
!     fprintf(log_fd, "> Adding state %d to list. Character %d: %s\n",
Karsten Hopp c7dad5
! 	abs(state->id), state->c, code);
Karsten Hopp c7dad5
  #endif
Karsten Hopp c7dad5
      switch (state->c)
Karsten Hopp c7dad5
      {
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 2588,2599 ****
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	case NFA_SPLIT:
Karsten Hopp c7dad5
! 	    addstate(l, state->out, m, off, lid);
Karsten Hopp c7dad5
! 	    addstate(l, state->out1, m, off, lid);
Karsten Hopp c7dad5
! 	    break;
Karsten Hopp c7dad5
! 
Karsten Hopp c7dad5
! 	case NFA_SKIP_CHAR:
Karsten Hopp c7dad5
! 	    addstate(l, state->out, m, off, lid);
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  #if 0
Karsten Hopp c7dad5
--- 2692,2699 ----
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	case NFA_SPLIT:
Karsten Hopp c7dad5
! 	    addstate(l, state->out, sub, off);
Karsten Hopp c7dad5
! 	    addstate(l, state->out1, sub, off);
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  #if 0
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 2613,2621 ****
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
  #endif
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	case NFA_NOPEN:
Karsten Hopp c7dad5
  	case NFA_NCLOSE:
Karsten Hopp c7dad5
! 	    addstate(l, state->out, m, off, lid);
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	/* If this state is reached, then a recursive call of nfa_regmatch()
Karsten Hopp c7dad5
--- 2713,2722 ----
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
  #endif
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
+ 	case NFA_SKIP_CHAR:
Karsten Hopp c7dad5
  	case NFA_NOPEN:
Karsten Hopp c7dad5
  	case NFA_NCLOSE:
Karsten Hopp c7dad5
! 	    addstate(l, state->out, sub, off);
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	/* If this state is reached, then a recursive call of nfa_regmatch()
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 2646,2709 ****
Karsten Hopp c7dad5
  	     * restore it when it was in use.  Otherwise fill any gap. */
Karsten Hopp c7dad5
  	    if (REG_MULTI)
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
! 		if (subidx < m->in_use)
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    save_lpos = m->multilist[subidx].start;
Karsten Hopp c7dad5
  		    save_in_use = -1;
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    save_in_use = m->in_use;
Karsten Hopp c7dad5
! 		    for (i = m->in_use; i < subidx; ++i)
Karsten Hopp c7dad5
  		    {
Karsten Hopp c7dad5
! 			m->multilist[i].start.lnum = -1;
Karsten Hopp c7dad5
! 			m->multilist[i].end.lnum = -1;
Karsten Hopp c7dad5
  		    }
Karsten Hopp c7dad5
! 		    m->in_use = subidx + 1;
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		if (off == -1)
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    m->multilist[subidx].start.lnum = reglnum + 1;
Karsten Hopp c7dad5
! 		    m->multilist[subidx].start.col = 0;
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    m->multilist[subidx].start.lnum = reglnum;
Karsten Hopp c7dad5
! 		    m->multilist[subidx].start.col =
Karsten Hopp c7dad5
  					  (colnr_T)(reginput - regline + off);
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  	    else
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
! 		if (subidx < m->in_use)
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    save_ptr = m->linelist[subidx].start;
Karsten Hopp c7dad5
  		    save_in_use = -1;
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    save_in_use = m->in_use;
Karsten Hopp c7dad5
! 		    for (i = m->in_use; i < subidx; ++i)
Karsten Hopp c7dad5
  		    {
Karsten Hopp c7dad5
! 			m->linelist[i].start = NULL;
Karsten Hopp c7dad5
! 			m->linelist[i].end = NULL;
Karsten Hopp c7dad5
  		    }
Karsten Hopp c7dad5
! 		    m->in_use = subidx + 1;
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
! 		m->linelist[subidx].start = reginput + off;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
! 	    addstate(l, state->out, m, off, lid);
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    if (save_in_use == -1)
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
  		if (REG_MULTI)
Karsten Hopp c7dad5
! 		    m->multilist[subidx].start = save_lpos;
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
! 		    m->linelist[subidx].start = save_ptr;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  	    else
Karsten Hopp c7dad5
! 		m->in_use = save_in_use;
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	case NFA_MCLOSE + 0:
Karsten Hopp c7dad5
--- 2747,2810 ----
Karsten Hopp c7dad5
  	     * restore it when it was in use.  Otherwise fill any gap. */
Karsten Hopp c7dad5
  	    if (REG_MULTI)
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
! 		if (subidx < sub->in_use)
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    save_lpos = sub->multilist[subidx].start;
Karsten Hopp c7dad5
  		    save_in_use = -1;
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    save_in_use = sub->in_use;
Karsten Hopp c7dad5
! 		    for (i = sub->in_use; i < subidx; ++i)
Karsten Hopp c7dad5
  		    {
Karsten Hopp c7dad5
! 			sub->multilist[i].start.lnum = -1;
Karsten Hopp c7dad5
! 			sub->multilist[i].end.lnum = -1;
Karsten Hopp c7dad5
  		    }
Karsten Hopp c7dad5
! 		    sub->in_use = subidx + 1;
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		if (off == -1)
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    sub->multilist[subidx].start.lnum = reglnum + 1;
Karsten Hopp c7dad5
! 		    sub->multilist[subidx].start.col = 0;
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    sub->multilist[subidx].start.lnum = reglnum;
Karsten Hopp c7dad5
! 		    sub->multilist[subidx].start.col =
Karsten Hopp c7dad5
  					  (colnr_T)(reginput - regline + off);
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  	    else
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
! 		if (subidx < sub->in_use)
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    save_ptr = sub->linelist[subidx].start;
Karsten Hopp c7dad5
  		    save_in_use = -1;
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    save_in_use = sub->in_use;
Karsten Hopp c7dad5
! 		    for (i = sub->in_use; i < subidx; ++i)
Karsten Hopp c7dad5
  		    {
Karsten Hopp c7dad5
! 			sub->linelist[i].start = NULL;
Karsten Hopp c7dad5
! 			sub->linelist[i].end = NULL;
Karsten Hopp c7dad5
  		    }
Karsten Hopp c7dad5
! 		    sub->in_use = subidx + 1;
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
! 		sub->linelist[subidx].start = reginput + off;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
! 	    addstate(l, state->out, sub, off);
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    if (save_in_use == -1)
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
  		if (REG_MULTI)
Karsten Hopp c7dad5
! 		    sub->multilist[subidx].start = save_lpos;
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
! 		    sub->linelist[subidx].start = save_ptr;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  	    else
Karsten Hopp c7dad5
! 		sub->in_use = save_in_use;
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	case NFA_MCLOSE + 0:
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 2711,2717 ****
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
  		/* Do not overwrite the position set by \ze. If no \ze
Karsten Hopp c7dad5
  		 * encountered end will be set in nfa_regtry(). */
Karsten Hopp c7dad5
! 		addstate(l, state->out, m, off, lid);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  	case NFA_MCLOSE + 1:
Karsten Hopp c7dad5
--- 2812,2818 ----
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
  		/* Do not overwrite the position set by \ze. If no \ze
Karsten Hopp c7dad5
  		 * encountered end will be set in nfa_regtry(). */
Karsten Hopp c7dad5
! 		addstate(l, state->out, sub, off);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  	case NFA_MCLOSE + 1:
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 2731,2767 ****
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    /* We don't fill in gaps here, there must have been an MOPEN that
Karsten Hopp c7dad5
  	     * has done that. */
Karsten Hopp c7dad5
! 	    save_in_use = m->in_use;
Karsten Hopp c7dad5
! 	    if (m->in_use <= subidx)
Karsten Hopp c7dad5
! 		m->in_use = subidx + 1;
Karsten Hopp c7dad5
  	    if (REG_MULTI)
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
! 		save_lpos = m->multilist[subidx].end;
Karsten Hopp c7dad5
  		if (off == -1)
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    m->multilist[subidx].end.lnum = reglnum + 1;
Karsten Hopp c7dad5
! 		    m->multilist[subidx].end.col = 0;
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    m->multilist[subidx].end.lnum = reglnum;
Karsten Hopp c7dad5
! 		    m->multilist[subidx].end.col =
Karsten Hopp c7dad5
  					  (colnr_T)(reginput - regline + off);
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  	    else
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
! 		save_ptr = m->linelist[subidx].end;
Karsten Hopp c7dad5
! 		m->linelist[subidx].end = reginput + off;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
! 	    addstate(l, state->out, m, off, lid);
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    if (REG_MULTI)
Karsten Hopp c7dad5
! 		m->multilist[subidx].end = save_lpos;
Karsten Hopp c7dad5
  	    else
Karsten Hopp c7dad5
! 		m->linelist[subidx].end = save_ptr;
Karsten Hopp c7dad5
! 	    m->in_use = save_in_use;
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
      }
Karsten Hopp c7dad5
  }
Karsten Hopp c7dad5
--- 2832,2868 ----
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    /* We don't fill in gaps here, there must have been an MOPEN that
Karsten Hopp c7dad5
  	     * has done that. */
Karsten Hopp c7dad5
! 	    save_in_use = sub->in_use;
Karsten Hopp c7dad5
! 	    if (sub->in_use <= subidx)
Karsten Hopp c7dad5
! 		sub->in_use = subidx + 1;
Karsten Hopp c7dad5
  	    if (REG_MULTI)
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
! 		save_lpos = sub->multilist[subidx].end;
Karsten Hopp c7dad5
  		if (off == -1)
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    sub->multilist[subidx].end.lnum = reglnum + 1;
Karsten Hopp c7dad5
! 		    sub->multilist[subidx].end.col = 0;
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
! 		    sub->multilist[subidx].end.lnum = reglnum;
Karsten Hopp c7dad5
! 		    sub->multilist[subidx].end.col =
Karsten Hopp c7dad5
  					  (colnr_T)(reginput - regline + off);
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  	    else
Karsten Hopp c7dad5
  	    {
Karsten Hopp c7dad5
! 		save_ptr = sub->linelist[subidx].end;
Karsten Hopp c7dad5
! 		sub->linelist[subidx].end = reginput + off;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
! 	    addstate(l, state->out, sub, off);
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    if (REG_MULTI)
Karsten Hopp c7dad5
! 		sub->multilist[subidx].end = save_lpos;
Karsten Hopp c7dad5
  	    else
Karsten Hopp c7dad5
! 		sub->linelist[subidx].end = save_ptr;
Karsten Hopp c7dad5
! 	    sub->in_use = save_in_use;
Karsten Hopp c7dad5
  	    break;
Karsten Hopp c7dad5
      }
Karsten Hopp c7dad5
  }
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 2773,2783 ****
Karsten Hopp c7dad5
   * matters for alternatives.
Karsten Hopp c7dad5
   */
Karsten Hopp c7dad5
      static void
Karsten Hopp c7dad5
! addstate_here(l, state, m, lid, ip)
Karsten Hopp c7dad5
      nfa_list_T		*l;	/* runtime state list */
Karsten Hopp c7dad5
      nfa_state_T		*state;	/* state to update */
Karsten Hopp c7dad5
!     regsub_T		*m;	/* pointers to subexpressions */
Karsten Hopp c7dad5
!     int			lid;
Karsten Hopp c7dad5
      int			*ip;
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
      int tlen = l->n;
Karsten Hopp c7dad5
--- 2874,2883 ----
Karsten Hopp c7dad5
   * matters for alternatives.
Karsten Hopp c7dad5
   */
Karsten Hopp c7dad5
      static void
Karsten Hopp c7dad5
! addstate_here(l, state, sub, ip)
Karsten Hopp c7dad5
      nfa_list_T		*l;	/* runtime state list */
Karsten Hopp c7dad5
      nfa_state_T		*state;	/* state to update */
Karsten Hopp c7dad5
!     regsub_T		*sub;	/* pointers to subexpressions */
Karsten Hopp c7dad5
      int			*ip;
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
      int tlen = l->n;
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 2785,2791 ****
Karsten Hopp c7dad5
      int i = *ip;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
      /* first add the state(s) at the end, so that we know how many there are */
Karsten Hopp c7dad5
!     addstate(l, state, m, 0, lid);
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
      /* when "*ip" was at the end of the list, nothing to do */
Karsten Hopp c7dad5
      if (i + 1 == tlen)
Karsten Hopp c7dad5
--- 2885,2891 ----
Karsten Hopp c7dad5
      int i = *ip;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
      /* first add the state(s) at the end, so that we know how many there are */
Karsten Hopp c7dad5
!     addstate(l, state, sub, 0);
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
      /* when "*ip" was at the end of the list, nothing to do */
Karsten Hopp c7dad5
      if (i + 1 == tlen)
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 2895,2900 ****
Karsten Hopp c7dad5
--- 2995,3052 ----
Karsten Hopp c7dad5
      return FAIL;
Karsten Hopp c7dad5
  }
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
+ static int match_backref __ARGS((regsub_T *sub, int subidx, int *bytelen));
Karsten Hopp c7dad5
+ 
Karsten Hopp c7dad5
+ /*
Karsten Hopp c7dad5
+  * Check for a match with subexpression "subidx".
Karsten Hopp c7dad5
+  * return TRUE if it matches.
Karsten Hopp c7dad5
+  */
Karsten Hopp c7dad5
+     static int
Karsten Hopp c7dad5
+ match_backref(sub, subidx, bytelen)
Karsten Hopp c7dad5
+     regsub_T	*sub;	    /* pointers to subexpressions */
Karsten Hopp c7dad5
+     int		subidx;
Karsten Hopp c7dad5
+     int		*bytelen;   /* out: length of match in bytes */
Karsten Hopp c7dad5
+ {
Karsten Hopp c7dad5
+     int		len;
Karsten Hopp c7dad5
+ 
Karsten Hopp c7dad5
+     if (sub->in_use <= subidx)
Karsten Hopp c7dad5
+     {
Karsten Hopp c7dad5
+ retempty:
Karsten Hopp c7dad5
+ 	/* backref was not set, match an empty string */
Karsten Hopp c7dad5
+ 	*bytelen = 0;
Karsten Hopp c7dad5
+ 	return TRUE;
Karsten Hopp c7dad5
+     }
Karsten Hopp c7dad5
+ 
Karsten Hopp c7dad5
+     if (REG_MULTI)
Karsten Hopp c7dad5
+     {
Karsten Hopp c7dad5
+ 	if (sub->multilist[subidx].start.lnum < 0
Karsten Hopp c7dad5
+ 				       || sub->multilist[subidx].end.lnum < 0)
Karsten Hopp c7dad5
+ 	    goto retempty;
Karsten Hopp c7dad5
+ 	/* TODO: line breaks */
Karsten Hopp c7dad5
+ 	len = sub->multilist[subidx].end.col
Karsten Hopp c7dad5
+ 					 - sub->multilist[subidx].start.col;
Karsten Hopp c7dad5
+ 	if (cstrncmp(regline + sub->multilist[subidx].start.col,
Karsten Hopp c7dad5
+ 							reginput, &len) == 0)
Karsten Hopp c7dad5
+ 	{
Karsten Hopp c7dad5
+ 	    *bytelen = len;
Karsten Hopp c7dad5
+ 	    return TRUE;
Karsten Hopp c7dad5
+ 	}
Karsten Hopp c7dad5
+     }
Karsten Hopp c7dad5
+     else
Karsten Hopp c7dad5
+     {
Karsten Hopp c7dad5
+ 	if (sub->linelist[subidx].start == NULL
Karsten Hopp c7dad5
+ 					 || sub->linelist[subidx].end == NULL)
Karsten Hopp c7dad5
+ 	    goto retempty;
Karsten Hopp c7dad5
+ 	len = (int)(sub->linelist[subidx].end - sub->linelist[subidx].start);
Karsten Hopp c7dad5
+ 	if (cstrncmp(sub->linelist[subidx].start, reginput, &len) == 0)
Karsten Hopp c7dad5
+ 	{
Karsten Hopp c7dad5
+ 	    *bytelen = len;
Karsten Hopp c7dad5
+ 	    return TRUE;
Karsten Hopp c7dad5
+ 	}
Karsten Hopp c7dad5
+     }
Karsten Hopp c7dad5
+     return FALSE;
Karsten Hopp c7dad5
+ }
Karsten Hopp c7dad5
+ 
Karsten Hopp c7dad5
  /*
Karsten Hopp c7dad5
   * Set all NFA nodes' list ID equal to -1.
Karsten Hopp c7dad5
   */
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 2902,2910 ****
Karsten Hopp c7dad5
  nfa_set_neg_listids(start)
Karsten Hopp c7dad5
      nfa_state_T	    *start;
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
!     if (start == NULL)
Karsten Hopp c7dad5
! 	return;
Karsten Hopp c7dad5
!     if (start->lastlist >= 0)
Karsten Hopp c7dad5
      {
Karsten Hopp c7dad5
  	start->lastlist = -1;
Karsten Hopp c7dad5
  	nfa_set_neg_listids(start->out);
Karsten Hopp c7dad5
--- 3054,3060 ----
Karsten Hopp c7dad5
  nfa_set_neg_listids(start)
Karsten Hopp c7dad5
      nfa_state_T	    *start;
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
!     if (start != NULL && start->lastlist >= 0)
Karsten Hopp c7dad5
      {
Karsten Hopp c7dad5
  	start->lastlist = -1;
Karsten Hopp c7dad5
  	nfa_set_neg_listids(start->out);
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 2919,2927 ****
Karsten Hopp c7dad5
  nfa_set_null_listids(start)
Karsten Hopp c7dad5
      nfa_state_T	    *start;
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
!     if (start == NULL)
Karsten Hopp c7dad5
! 	return;
Karsten Hopp c7dad5
!     if (start->lastlist == -1)
Karsten Hopp c7dad5
      {
Karsten Hopp c7dad5
  	start->lastlist = 0;
Karsten Hopp c7dad5
  	nfa_set_null_listids(start->out);
Karsten Hopp c7dad5
--- 3069,3075 ----
Karsten Hopp c7dad5
  nfa_set_null_listids(start)
Karsten Hopp c7dad5
      nfa_state_T	    *start;
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
!     if (start != NULL && start->lastlist == -1)
Karsten Hopp c7dad5
      {
Karsten Hopp c7dad5
  	start->lastlist = 0;
Karsten Hopp c7dad5
  	nfa_set_null_listids(start->out);
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 2937,2945 ****
Karsten Hopp c7dad5
      nfa_state_T	    *start;
Karsten Hopp c7dad5
      int		    *list;
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
!     if (start == NULL)
Karsten Hopp c7dad5
! 	return;
Karsten Hopp c7dad5
!     if (start->lastlist != -1)
Karsten Hopp c7dad5
      {
Karsten Hopp c7dad5
  	list[abs(start->id)] = start->lastlist;
Karsten Hopp c7dad5
  	start->lastlist = -1;
Karsten Hopp c7dad5
--- 3085,3091 ----
Karsten Hopp c7dad5
      nfa_state_T	    *start;
Karsten Hopp c7dad5
      int		    *list;
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
!     if (start != NULL && start->lastlist != -1)
Karsten Hopp c7dad5
      {
Karsten Hopp c7dad5
  	list[abs(start->id)] = start->lastlist;
Karsten Hopp c7dad5
  	start->lastlist = -1;
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 2956,2964 ****
Karsten Hopp c7dad5
      nfa_state_T	    *start;
Karsten Hopp c7dad5
      int		    *list;
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
!     if (start == NULL)
Karsten Hopp c7dad5
! 	return;
Karsten Hopp c7dad5
!     if (start->lastlist == -1)
Karsten Hopp c7dad5
      {
Karsten Hopp c7dad5
  	start->lastlist = list[abs(start->id)];
Karsten Hopp c7dad5
  	nfa_restore_listids(start->out, list);
Karsten Hopp c7dad5
--- 3102,3108 ----
Karsten Hopp c7dad5
      nfa_state_T	    *start;
Karsten Hopp c7dad5
      int		    *list;
Karsten Hopp c7dad5
  {
Karsten Hopp c7dad5
!     if (start != NULL && start->lastlist == -1)
Karsten Hopp c7dad5
      {
Karsten Hopp c7dad5
  	start->lastlist = list[abs(start->id)];
Karsten Hopp c7dad5
  	nfa_restore_listids(start->out, list);
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 3047,3053 ****
Karsten Hopp c7dad5
  #ifdef ENABLE_LOG
Karsten Hopp c7dad5
      fprintf(log_fd, "(---) STARTSTATE\n");
Karsten Hopp c7dad5
  #endif
Karsten Hopp c7dad5
!     addstate(thislist, start, m, 0, listid);
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
      /* There are two cases when the NFA advances: 1. input char matches the
Karsten Hopp c7dad5
       * NFA node and 2. input char does not match the NFA node, but the next
Karsten Hopp c7dad5
--- 3191,3198 ----
Karsten Hopp c7dad5
  #ifdef ENABLE_LOG
Karsten Hopp c7dad5
      fprintf(log_fd, "(---) STARTSTATE\n");
Karsten Hopp c7dad5
  #endif
Karsten Hopp c7dad5
!     thislist->id = listid;
Karsten Hopp c7dad5
!     addstate(thislist, start, m, 0);
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
      /* There are two cases when the NFA advances: 1. input char matches the
Karsten Hopp c7dad5
       * NFA node and 2. input char does not match the NFA node, but the next
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 3060,3066 ****
Karsten Hopp c7dad5
  #define	ADD_POS_NEG_STATE(node)						    \
Karsten Hopp c7dad5
      ll = listtbl[result ? 1 : 0][node->negated];			    \
Karsten Hopp c7dad5
      if (ll != NULL)							    \
Karsten Hopp c7dad5
! 	addstate(ll, node->out , &t->sub, clen, listid + 1);
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
      /*
Karsten Hopp c7dad5
--- 3205,3211 ----
Karsten Hopp c7dad5
  #define	ADD_POS_NEG_STATE(node)						    \
Karsten Hopp c7dad5
      ll = listtbl[result ? 1 : 0][node->negated];			    \
Karsten Hopp c7dad5
      if (ll != NULL)							    \
Karsten Hopp c7dad5
! 	addstate(ll, node->out , &t->sub, clen);
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
      /*
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 3092,3100 ****
Karsten Hopp c7dad5
  	/* swap lists */
Karsten Hopp c7dad5
  	thislist = &list[flag];
Karsten Hopp c7dad5
  	nextlist = &list[flag ^= 1];
Karsten Hopp c7dad5
! 	nextlist->n = 0;	    /* `clear' nextlist */
Karsten Hopp c7dad5
  	listtbl[1][0] = nextlist;
Karsten Hopp c7dad5
  	++listid;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  #ifdef ENABLE_LOG
Karsten Hopp c7dad5
  	fprintf(log_fd, "------------------------------------------\n");
Karsten Hopp c7dad5
--- 3237,3248 ----
Karsten Hopp c7dad5
  	/* swap lists */
Karsten Hopp c7dad5
  	thislist = &list[flag];
Karsten Hopp c7dad5
  	nextlist = &list[flag ^= 1];
Karsten Hopp c7dad5
! 	nextlist->n = 0;	    /* clear nextlist */
Karsten Hopp c7dad5
  	listtbl[1][0] = nextlist;
Karsten Hopp c7dad5
  	++listid;
Karsten Hopp c7dad5
+ 	thislist->id = listid;
Karsten Hopp c7dad5
+ 	nextlist->id = listid + 1;
Karsten Hopp c7dad5
+ 	neglist->id = listid + 1;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  #ifdef ENABLE_LOG
Karsten Hopp c7dad5
  	fprintf(log_fd, "------------------------------------------\n");
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 3156,3162 ****
Karsten Hopp c7dad5
  		if (REG_MULTI)
Karsten Hopp c7dad5
  		    for (j = 0; j < submatch->in_use; j++)
Karsten Hopp c7dad5
  		    {
Karsten Hopp c7dad5
! 			submatch->multilist[j].start = t->sub.multilist[j].start;
Karsten Hopp c7dad5
  			submatch->multilist[j].end = t->sub.multilist[j].end;
Karsten Hopp c7dad5
  		    }
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
--- 3304,3311 ----
Karsten Hopp c7dad5
  		if (REG_MULTI)
Karsten Hopp c7dad5
  		    for (j = 0; j < submatch->in_use; j++)
Karsten Hopp c7dad5
  		    {
Karsten Hopp c7dad5
! 			submatch->multilist[j].start =
Karsten Hopp c7dad5
! 						    t->sub.multilist[j].start;
Karsten Hopp c7dad5
  			submatch->multilist[j].end = t->sub.multilist[j].end;
Karsten Hopp c7dad5
  		    }
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 3166,3185 ****
Karsten Hopp c7dad5
  			submatch->linelist[j].end = t->sub.linelist[j].end;
Karsten Hopp c7dad5
  		    }
Karsten Hopp c7dad5
  #ifdef ENABLE_LOG
Karsten Hopp c7dad5
! 		for (j = 0; j < t->sub.in_use; j++)
Karsten Hopp c7dad5
! 		    if (REG_MULTI)
Karsten Hopp c7dad5
! 			fprintf(log_fd, "\n *** group %d, start: c=%d, l=%d, end: c=%d, l=%d",
Karsten Hopp c7dad5
! 				j,
Karsten Hopp c7dad5
! 				t->sub.multilist[j].start.col,
Karsten Hopp c7dad5
! 				(int)t->sub.multilist[j].start.lnum,
Karsten Hopp c7dad5
! 				t->sub.multilist[j].end.col,
Karsten Hopp c7dad5
! 				(int)t->sub.multilist[j].end.lnum);
Karsten Hopp c7dad5
! 		    else
Karsten Hopp c7dad5
! 			fprintf(log_fd, "\n *** group %d, start: \"%s\", end: \"%s\"",
Karsten Hopp c7dad5
! 				j,
Karsten Hopp c7dad5
! 				(char *)t->sub.linelist[j].start,
Karsten Hopp c7dad5
! 				(char *)t->sub.linelist[j].end);
Karsten Hopp c7dad5
! 		fprintf(log_fd, "\n");
Karsten Hopp c7dad5
  #endif
Karsten Hopp c7dad5
  		/* Found the left-most longest match, do not look at any other
Karsten Hopp c7dad5
  		 * states at this position.  When the list of states is going
Karsten Hopp c7dad5
--- 3315,3321 ----
Karsten Hopp c7dad5
  			submatch->linelist[j].end = t->sub.linelist[j].end;
Karsten Hopp c7dad5
  		    }
Karsten Hopp c7dad5
  #ifdef ENABLE_LOG
Karsten Hopp c7dad5
! 		log_subexpr(&t->sub);
Karsten Hopp c7dad5
  #endif
Karsten Hopp c7dad5
  		/* Found the left-most longest match, do not look at any other
Karsten Hopp c7dad5
  		 * states at this position.  When the list of states is going
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 3198,3205 ****
Karsten Hopp c7dad5
  		 * nfa_regmatch().  Submatches are stored in *m, and used in
Karsten Hopp c7dad5
  		 * the parent call. */
Karsten Hopp c7dad5
  		if (start->c == NFA_MOPEN + 0)
Karsten Hopp c7dad5
! 		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp c7dad5
! 								    &listidx);
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
  		    *m = t->sub;
Karsten Hopp c7dad5
--- 3334,3340 ----
Karsten Hopp c7dad5
  		 * nfa_regmatch().  Submatches are stored in *m, and used in
Karsten Hopp c7dad5
  		 * the parent call. */
Karsten Hopp c7dad5
  		if (start->c == NFA_MOPEN + 0)
Karsten Hopp c7dad5
! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
  		    *m = t->sub;
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 3277,3283 ****
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  		    /* t->state->out1 is the corresponding END_INVISIBLE node */
Karsten Hopp c7dad5
  		    addstate_here(thislist, t->state->out1->out, &t->sub,
Karsten Hopp c7dad5
! 							    listid, &listidx);
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
--- 3412,3418 ----
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  		    /* t->state->out1 is the corresponding END_INVISIBLE node */
Karsten Hopp c7dad5
  		    addstate_here(thislist, t->state->out1->out, &t->sub,
Karsten Hopp c7dad5
! 								    &listidx);
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		else
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 3288,3301 ****
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    case NFA_BOL:
Karsten Hopp c7dad5
  		if (reginput == regline)
Karsten Hopp c7dad5
! 		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp c7dad5
! 								    &listidx);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    case NFA_EOL:
Karsten Hopp c7dad5
  		if (curc == NUL)
Karsten Hopp c7dad5
! 		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp c7dad5
! 								    &listidx);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    case NFA_BOW:
Karsten Hopp c7dad5
--- 3423,3434 ----
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    case NFA_BOL:
Karsten Hopp c7dad5
  		if (reginput == regline)
Karsten Hopp c7dad5
! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    case NFA_EOL:
Karsten Hopp c7dad5
  		if (curc == NUL)
Karsten Hopp c7dad5
! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    case NFA_BOW:
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 3322,3329 ****
Karsten Hopp c7dad5
  				   && vim_iswordc_buf(reginput[-1], reg_buf)))
Karsten Hopp c7dad5
  		    bow = FALSE;
Karsten Hopp c7dad5
  		if (bow)
Karsten Hopp c7dad5
! 		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp c7dad5
! 								    &listidx);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
--- 3455,3461 ----
Karsten Hopp c7dad5
  				   && vim_iswordc_buf(reginput[-1], reg_buf)))
Karsten Hopp c7dad5
  		    bow = FALSE;
Karsten Hopp c7dad5
  		if (bow)
Karsten Hopp c7dad5
! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 3351,3358 ****
Karsten Hopp c7dad5
  					   && vim_iswordc_buf(curc, reg_buf)))
Karsten Hopp c7dad5
  		    eow = FALSE;
Karsten Hopp c7dad5
  		if (eow)
Karsten Hopp c7dad5
! 		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp c7dad5
! 								    &listidx);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
--- 3483,3489 ----
Karsten Hopp c7dad5
  					   && vim_iswordc_buf(curc, reg_buf)))
Karsten Hopp c7dad5
  		    eow = FALSE;
Karsten Hopp c7dad5
  		if (eow)
Karsten Hopp c7dad5
! 		    addstate_here(thislist, t->state->out, &t->sub, &listidx);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  	    }
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 3442,3453 ****
Karsten Hopp c7dad5
  		    go_to_nextline = TRUE;
Karsten Hopp c7dad5
  		    /* Pass -1 for the offset, which means taking the position
Karsten Hopp c7dad5
  		     * at the start of the next line. */
Karsten Hopp c7dad5
! 		    addstate(nextlist, t->state->out, &t->sub, -1, listid + 1);
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		else if (curc == '\n' && reg_line_lbr)
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
  		    /* match \n as if it is an ordinary character */
Karsten Hopp c7dad5
! 		    addstate(nextlist, t->state->out, &t->sub, 1, listid + 1);
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
--- 3573,3584 ----
Karsten Hopp c7dad5
  		    go_to_nextline = TRUE;
Karsten Hopp c7dad5
  		    /* Pass -1 for the offset, which means taking the position
Karsten Hopp c7dad5
  		     * at the start of the next line. */
Karsten Hopp c7dad5
! 		    addstate(nextlist, t->state->out, &t->sub, -1);
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		else if (curc == '\n' && reg_line_lbr)
Karsten Hopp c7dad5
  		{
Karsten Hopp c7dad5
  		    /* match \n as if it is an ordinary character */
Karsten Hopp c7dad5
! 		    addstate(nextlist, t->state->out, &t->sub, 1);
Karsten Hopp c7dad5
  		}
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 3475,3489 ****
Karsten Hopp c7dad5
  		/* This follows a series of negated nodes, like:
Karsten Hopp c7dad5
  		 * CHAR(x), NFA_NOT, CHAR(y), NFA_NOT etc. */
Karsten Hopp c7dad5
  		if (curc > 0)
Karsten Hopp c7dad5
! 		    addstate(nextlist, t->state->out, &t->sub, clen,
Karsten Hopp c7dad5
! 								  listid + 1);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    case NFA_ANY:
Karsten Hopp c7dad5
  		/* Any char except '\0', (end of input) does not match. */
Karsten Hopp c7dad5
  		if (curc > 0)
Karsten Hopp c7dad5
! 		    addstate(nextlist, t->state->out, &t->sub, clen,
Karsten Hopp c7dad5
! 								  listid + 1);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    /*
Karsten Hopp c7dad5
--- 3606,3618 ----
Karsten Hopp c7dad5
  		/* This follows a series of negated nodes, like:
Karsten Hopp c7dad5
  		 * CHAR(x), NFA_NOT, CHAR(y), NFA_NOT etc. */
Karsten Hopp c7dad5
  		if (curc > 0)
Karsten Hopp c7dad5
! 		    addstate(nextlist, t->state->out, &t->sub, clen);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    case NFA_ANY:
Karsten Hopp c7dad5
  		/* Any char except '\0', (end of input) does not match. */
Karsten Hopp c7dad5
  		if (curc > 0)
Karsten Hopp c7dad5
! 		    addstate(nextlist, t->state->out, &t->sub, clen);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    /*
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 3620,3637 ****
Karsten Hopp c7dad5
  		ADD_POS_NEG_STATE(t->state);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
! 	    case NFA_MOPEN + 0:
Karsten Hopp c7dad5
! 	    case NFA_MOPEN + 1:
Karsten Hopp c7dad5
! 	    case NFA_MOPEN + 2:
Karsten Hopp c7dad5
! 	    case NFA_MOPEN + 3:
Karsten Hopp c7dad5
! 	    case NFA_MOPEN + 4:
Karsten Hopp c7dad5
! 	    case NFA_MOPEN + 5:
Karsten Hopp c7dad5
! 	    case NFA_MOPEN + 6:
Karsten Hopp c7dad5
! 	    case NFA_MOPEN + 7:
Karsten Hopp c7dad5
! 	    case NFA_MOPEN + 8:
Karsten Hopp c7dad5
! 	    case NFA_MOPEN + 9:
Karsten Hopp c7dad5
! 		/* handled below */
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    case NFA_SKIP_CHAR:
Karsten Hopp c7dad5
  	    case NFA_ZSTART:
Karsten Hopp c7dad5
--- 3749,3822 ----
Karsten Hopp c7dad5
  		ADD_POS_NEG_STATE(t->state);
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
! 	    case NFA_BACKREF1:
Karsten Hopp c7dad5
! 	    case NFA_BACKREF2:
Karsten Hopp c7dad5
! 	    case NFA_BACKREF3:
Karsten Hopp c7dad5
! 	    case NFA_BACKREF4:
Karsten Hopp c7dad5
! 	    case NFA_BACKREF5:
Karsten Hopp c7dad5
! 	    case NFA_BACKREF6:
Karsten Hopp c7dad5
! 	    case NFA_BACKREF7:
Karsten Hopp c7dad5
! 	    case NFA_BACKREF8:
Karsten Hopp c7dad5
! 	    case NFA_BACKREF9:
Karsten Hopp c7dad5
! 		/* \1 .. \9 */
Karsten Hopp c7dad5
! 	      {
Karsten Hopp c7dad5
! 		int subidx = t->state->c - NFA_BACKREF1 + 1;
Karsten Hopp c7dad5
! 		int bytelen;
Karsten Hopp c7dad5
! 
Karsten Hopp c7dad5
! 		result = match_backref(&t->sub, subidx, &bytelen);
Karsten Hopp c7dad5
! 		if (result)
Karsten Hopp c7dad5
! 		{
Karsten Hopp c7dad5
! 		    if (bytelen == 0)
Karsten Hopp c7dad5
! 		    {
Karsten Hopp c7dad5
! 			/* empty match always works, add NFA_SKIP with zero to
Karsten Hopp c7dad5
! 			 * be used next */
Karsten Hopp c7dad5
! 			addstate_here(thislist, t->state->out, &t->sub,
Karsten Hopp c7dad5
! 								    &listidx);
Karsten Hopp c7dad5
! 			thislist->t[listidx + 1].count = 0;
Karsten Hopp c7dad5
! 		    }
Karsten Hopp c7dad5
! 		    else if (bytelen <= clen)
Karsten Hopp c7dad5
! 		    {
Karsten Hopp c7dad5
! 			/* match current character, jump ahead to out of
Karsten Hopp c7dad5
! 			 * NFA_SKIP */
Karsten Hopp c7dad5
! 			addstate(nextlist, t->state->out->out, &t->sub, clen);
Karsten Hopp c7dad5
! #ifdef ENABLE_LOG
Karsten Hopp c7dad5
! 			log_subexpr(&nextlist->t[nextlist->n - 1].sub);
Karsten Hopp c7dad5
! #endif
Karsten Hopp c7dad5
! 		    }
Karsten Hopp c7dad5
! 		    else
Karsten Hopp c7dad5
! 		    {
Karsten Hopp c7dad5
! 			/* skip ofer the matched characters, set character
Karsten Hopp c7dad5
! 			 * count in NFA_SKIP */
Karsten Hopp c7dad5
! 			addstate(nextlist, t->state->out, &t->sub, bytelen);
Karsten Hopp c7dad5
! 			nextlist->t[nextlist->n - 1].count = bytelen - clen;
Karsten Hopp c7dad5
! #ifdef ENABLE_LOG
Karsten Hopp c7dad5
! 			log_subexpr(&nextlist->t[nextlist->n - 1].sub);
Karsten Hopp c7dad5
! #endif
Karsten Hopp c7dad5
! 		    }
Karsten Hopp c7dad5
! 
Karsten Hopp c7dad5
! 		}
Karsten Hopp c7dad5
  		break;
Karsten Hopp c7dad5
+ 	      }
Karsten Hopp c7dad5
+ 	    case NFA_SKIP:
Karsten Hopp c7dad5
+ 	      /* charater of previous matching \1 .. \9 */
Karsten Hopp c7dad5
+ 	      if (t->count - clen <= 0)
Karsten Hopp c7dad5
+ 	      {
Karsten Hopp c7dad5
+ 		  /* end of match, go to what follows */
Karsten Hopp c7dad5
+ 		  addstate(nextlist, t->state->out, &t->sub, clen);
Karsten Hopp c7dad5
+ #ifdef ENABLE_LOG
Karsten Hopp c7dad5
+ 		  log_subexpr(&nextlist->t[nextlist->n - 1].sub);
Karsten Hopp c7dad5
+ #endif
Karsten Hopp c7dad5
+ 	      }
Karsten Hopp c7dad5
+ 	      else
Karsten Hopp c7dad5
+ 	      {
Karsten Hopp c7dad5
+ 		  /* add state again with decremented count */
Karsten Hopp c7dad5
+ 		  addstate(nextlist, t->state, &t->sub, 0);
Karsten Hopp c7dad5
+ 		  nextlist->t[nextlist->n - 1].count = t->count - clen;
Karsten Hopp c7dad5
+ #ifdef ENABLE_LOG
Karsten Hopp c7dad5
+ 		  log_subexpr(&nextlist->t[nextlist->n - 1].sub);
Karsten Hopp c7dad5
+ #endif
Karsten Hopp c7dad5
+ 	      }
Karsten Hopp c7dad5
+ 	      break;
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  	    case NFA_SKIP_CHAR:
Karsten Hopp c7dad5
  	    case NFA_ZSTART:
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 3680,3686 ****
Karsten Hopp c7dad5
  #ifdef ENABLE_LOG
Karsten Hopp c7dad5
  	    fprintf(log_fd, "(---) STARTSTATE\n");
Karsten Hopp c7dad5
  #endif
Karsten Hopp c7dad5
! 	    addstate(nextlist, start, m, clen, listid + 1);
Karsten Hopp c7dad5
  	}
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  #ifdef ENABLE_LOG
Karsten Hopp c7dad5
--- 3865,3871 ----
Karsten Hopp c7dad5
  #ifdef ENABLE_LOG
Karsten Hopp c7dad5
  	    fprintf(log_fd, "(---) STARTSTATE\n");
Karsten Hopp c7dad5
  #endif
Karsten Hopp c7dad5
! 	    addstate(nextlist, start, m, clen);
Karsten Hopp c7dad5
  	}
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
  #ifdef ENABLE_LOG
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 3884,3890 ****
Karsten Hopp c7dad5
      {
Karsten Hopp c7dad5
  	prog->state[i].id = i;
Karsten Hopp c7dad5
  	prog->state[i].lastlist = 0;
Karsten Hopp c7dad5
- 	prog->state[i].visits = 0;
Karsten Hopp c7dad5
      }
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
      retval = nfa_regtry(prog->start, col);
Karsten Hopp c7dad5
--- 4069,4074 ----
Karsten Hopp c7dad5
*** ../vim-7.3.1032/src/testdir/test64.in	2013-05-27 20:10:40.000000000 +0200
Karsten Hopp c7dad5
--- src/testdir/test64.in	2013-05-28 20:24:11.000000000 +0200
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 331,336 ****
Karsten Hopp c7dad5
--- 331,340 ----
Karsten Hopp c7dad5
  :call add(tl, [2, '\
Karsten Hopp c7dad5
  :call add(tl, [2, '\
Karsten Hopp c7dad5
  :"
Karsten Hopp c7dad5
+ :"""" Back references
Karsten Hopp c7dad5
+ :call add(tl, [2, '\(\i\+\) \1', ' abc abc', 'abc abc', 'abc'])
Karsten Hopp c7dad5
+ :"call add(tl, [2, '\(\i\+\) \1', 'xgoo goox', 'goo goo', 'goo'])
Karsten Hopp c7dad5
+ :call add(tl, [2, '\(a\)\(b\)\(c\)\(dd\)\(e\)\(f\)\(g\)\(h\)\(i\)\1\2\3\4\5\6\7\8\9', 'xabcddefghiabcddefghix', 'abcddefghiabcddefghi', 'a', 'b', 'c', 'dd', 'e', 'f', 'g', 'h', 'i'])
Karsten Hopp c7dad5
  :"
Karsten Hopp c7dad5
  :"""" Run the tests
Karsten Hopp c7dad5
  :"
Karsten Hopp c7dad5
*** ../vim-7.3.1032/src/testdir/test64.ok	2013-05-27 20:10:40.000000000 +0200
Karsten Hopp c7dad5
--- src/testdir/test64.ok	2013-05-28 20:24:19.000000000 +0200
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 713,718 ****
Karsten Hopp c7dad5
--- 713,724 ----
Karsten Hopp c7dad5
  OK 0 - \
Karsten Hopp c7dad5
  OK 1 - \
Karsten Hopp c7dad5
  OK 2 - \
Karsten Hopp c7dad5
+ OK 0 - \(\i\+\) \1
Karsten Hopp c7dad5
+ OK 1 - \(\i\+\) \1
Karsten Hopp c7dad5
+ OK 2 - \(\i\+\) \1
Karsten Hopp c7dad5
+ OK 0 - \(a\)\(b\)\(c\)\(dd\)\(e\)\(f\)\(g\)\(h\)\(i\)\1\2\3\4\5\6\7\8\9
Karsten Hopp c7dad5
+ OK 1 - \(a\)\(b\)\(c\)\(dd\)\(e\)\(f\)\(g\)\(h\)\(i\)\1\2\3\4\5\6\7\8\9
Karsten Hopp c7dad5
+ OK 2 - \(a\)\(b\)\(c\)\(dd\)\(e\)\(f\)\(g\)\(h\)\(i\)\1\2\3\4\5\6\7\8\9
Karsten Hopp c7dad5
  192.168.0.1
Karsten Hopp c7dad5
  192.168.0.1
Karsten Hopp c7dad5
  192.168.0.1
Karsten Hopp c7dad5
*** ../vim-7.3.1032/src/regexp.h	2013-05-26 21:47:22.000000000 +0200
Karsten Hopp c7dad5
--- src/regexp.h	2013-05-28 21:50:56.000000000 +0200
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 71,77 ****
Karsten Hopp c7dad5
      nfa_state_T		*out1;
Karsten Hopp c7dad5
      int			id;
Karsten Hopp c7dad5
      int			lastlist;
Karsten Hopp c7dad5
-     int			visits;
Karsten Hopp c7dad5
      int			negated;
Karsten Hopp c7dad5
  };
Karsten Hopp c7dad5
  
Karsten Hopp c7dad5
--- 71,76 ----
Karsten Hopp c7dad5
*** ../vim-7.3.1032/src/version.c	2013-05-27 20:10:40.000000000 +0200
Karsten Hopp c7dad5
--- src/version.c	2013-05-28 22:01:32.000000000 +0200
Karsten Hopp c7dad5
***************
Karsten Hopp c7dad5
*** 730,731 ****
Karsten Hopp c7dad5
--- 730,733 ----
Karsten Hopp c7dad5
  {   /* Add new patch number below this line */
Karsten Hopp c7dad5
+ /**/
Karsten Hopp c7dad5
+     1033,
Karsten Hopp c7dad5
  /**/
Karsten Hopp c7dad5
Karsten Hopp c7dad5
-- 
Karsten Hopp c7dad5
Everybody wants to go to heaven, but nobody wants to die.
Karsten Hopp c7dad5
Karsten Hopp c7dad5
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp c7dad5
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp c7dad5
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp c7dad5
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///