Karsten Hopp 5e4d4a
To: vim_dev@googlegroups.com
Karsten Hopp 5e4d4a
Subject: Patch 7.3.1137
Karsten Hopp 5e4d4a
Fcc: outbox
Karsten Hopp 5e4d4a
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 5e4d4a
Mime-Version: 1.0
Karsten Hopp 5e4d4a
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 5e4d4a
Content-Transfer-Encoding: 8bit
Karsten Hopp 5e4d4a
------------
Karsten Hopp 5e4d4a
Karsten Hopp 5e4d4a
Patch 7.3.1137
Karsten Hopp 5e4d4a
Problem:    New regexp engine: collections are slow.
Karsten Hopp 5e4d4a
Solution:   Handle all characters in one go.
Karsten Hopp 5e4d4a
Files:	    src/regexp_nfa.c
Karsten Hopp 5e4d4a
Karsten Hopp 5e4d4a
Karsten Hopp 5e4d4a
*** ../vim-7.3.1136/src/regexp_nfa.c	2013-06-06 18:46:00.000000000 +0200
Karsten Hopp 5e4d4a
--- src/regexp_nfa.c	2013-06-07 13:40:58.000000000 +0200
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 34,48 ****
Karsten Hopp 5e4d4a
      NFA_SPLIT = -1024,
Karsten Hopp 5e4d4a
      NFA_MATCH,
Karsten Hopp 5e4d4a
      NFA_SKIP_CHAR,		    /* matches a 0-length char */
Karsten Hopp 5e4d4a
-     NFA_END_NEG_RANGE,		    /* Used when expanding [^ab] */
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
!     NFA_CONCAT,
Karsten Hopp 5e4d4a
      NFA_OR,
Karsten Hopp 5e4d4a
      NFA_STAR,			    /* greedy * */
Karsten Hopp 5e4d4a
      NFA_STAR_NONGREEDY,		    /* non-greedy * */
Karsten Hopp 5e4d4a
      NFA_QUEST,			    /* greedy \? */
Karsten Hopp 5e4d4a
      NFA_QUEST_NONGREEDY,	    /* non-greedy \? */
Karsten Hopp 5e4d4a
-     NFA_NOT,			    /* used for [^ab] negated char ranges */
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
      NFA_BOL,			    /* ^    Begin line */
Karsten Hopp 5e4d4a
      NFA_EOL,			    /* $    End line */
Karsten Hopp 5e4d4a
--- 34,56 ----
Karsten Hopp 5e4d4a
      NFA_SPLIT = -1024,
Karsten Hopp 5e4d4a
      NFA_MATCH,
Karsten Hopp 5e4d4a
      NFA_SKIP_CHAR,		    /* matches a 0-length char */
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
!     NFA_START_COLL,		    /* [abc] start */
Karsten Hopp 5e4d4a
!     NFA_END_COLL,		    /* [abc] end */
Karsten Hopp 5e4d4a
!     NFA_START_NEG_COLL,		    /* [^abc] start */
Karsten Hopp 5e4d4a
!     NFA_END_NEG_COLL,		    /* [^abc] end (only used in postfix) */
Karsten Hopp 5e4d4a
!     NFA_RANGE,			    /* range of the two previous items (only
Karsten Hopp 5e4d4a
! 				     * used in postfix) */
Karsten Hopp 5e4d4a
!     NFA_RANGE_MIN,		    /* low end of a range  */
Karsten Hopp 5e4d4a
!     NFA_RANGE_MAX,		    /* high end of a range  */
Karsten Hopp 5e4d4a
! 
Karsten Hopp 5e4d4a
!     NFA_CONCAT,			    /* concatenate two previous items (only
Karsten Hopp 5e4d4a
! 				     * used in postfix) */
Karsten Hopp 5e4d4a
      NFA_OR,
Karsten Hopp 5e4d4a
      NFA_STAR,			    /* greedy * */
Karsten Hopp 5e4d4a
      NFA_STAR_NONGREEDY,		    /* non-greedy * */
Karsten Hopp 5e4d4a
      NFA_QUEST,			    /* greedy \? */
Karsten Hopp 5e4d4a
      NFA_QUEST_NONGREEDY,	    /* non-greedy \? */
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
      NFA_BOL,			    /* ^    Begin line */
Karsten Hopp 5e4d4a
      NFA_EOL,			    /* $    End line */
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 260,266 ****
Karsten Hopp 5e4d4a
  static int nfa_get_reganch __ARGS((nfa_state_T *start, int depth));
Karsten Hopp 5e4d4a
  static int nfa_get_regstart __ARGS((nfa_state_T *start, int depth));
Karsten Hopp 5e4d4a
  static int nfa_recognize_char_class __ARGS((char_u *start, char_u *end, int extra_newl));
Karsten Hopp 5e4d4a
! static int nfa_emit_equi_class __ARGS((int c, int neg));
Karsten Hopp 5e4d4a
  static int nfa_regatom __ARGS((void));
Karsten Hopp 5e4d4a
  static int nfa_regpiece __ARGS((void));
Karsten Hopp 5e4d4a
  static int nfa_regconcat __ARGS((void));
Karsten Hopp 5e4d4a
--- 268,274 ----
Karsten Hopp 5e4d4a
  static int nfa_get_reganch __ARGS((nfa_state_T *start, int depth));
Karsten Hopp 5e4d4a
  static int nfa_get_regstart __ARGS((nfa_state_T *start, int depth));
Karsten Hopp 5e4d4a
  static int nfa_recognize_char_class __ARGS((char_u *start, char_u *end, int extra_newl));
Karsten Hopp 5e4d4a
! static int nfa_emit_equi_class __ARGS((int c));
Karsten Hopp 5e4d4a
  static int nfa_regatom __ARGS((void));
Karsten Hopp 5e4d4a
  static int nfa_regpiece __ARGS((void));
Karsten Hopp 5e4d4a
  static int nfa_regconcat __ARGS((void));
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 664,684 ****
Karsten Hopp 5e4d4a
   * NOTE! When changing this function, also update reg_equi_class()
Karsten Hopp 5e4d4a
   */
Karsten Hopp 5e4d4a
      static int
Karsten Hopp 5e4d4a
! nfa_emit_equi_class(c, neg)
Karsten Hopp 5e4d4a
      int	    c;
Karsten Hopp 5e4d4a
-     int	    neg;
Karsten Hopp 5e4d4a
  {
Karsten Hopp 5e4d4a
!     int	first = TRUE;
Karsten Hopp 5e4d4a
!     int	glue = neg == TRUE ? NFA_CONCAT : NFA_OR;
Karsten Hopp 5e4d4a
! #define EMIT2(c)		\
Karsten Hopp 5e4d4a
! 	EMIT(c);		\
Karsten Hopp 5e4d4a
! 	if (neg == TRUE) {	\
Karsten Hopp 5e4d4a
! 	    EMIT(NFA_NOT);	\
Karsten Hopp 5e4d4a
! 	}			\
Karsten Hopp 5e4d4a
! 	if (first == FALSE)	\
Karsten Hopp 5e4d4a
! 	    EMIT(glue);		\
Karsten Hopp 5e4d4a
! 	else			\
Karsten Hopp 5e4d4a
! 	    first = FALSE;	\
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  #ifdef FEAT_MBYTE
Karsten Hopp 5e4d4a
      if (enc_utf8 || STRCMP(p_enc, "latin1") == 0
Karsten Hopp 5e4d4a
--- 672,681 ----
Karsten Hopp 5e4d4a
   * NOTE! When changing this function, also update reg_equi_class()
Karsten Hopp 5e4d4a
   */
Karsten Hopp 5e4d4a
      static int
Karsten Hopp 5e4d4a
! nfa_emit_equi_class(c)
Karsten Hopp 5e4d4a
      int	    c;
Karsten Hopp 5e4d4a
  {
Karsten Hopp 5e4d4a
! #define EMIT2(c)   EMIT(c); EMIT(NFA_CONCAT);
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  #ifdef FEAT_MBYTE
Karsten Hopp 5e4d4a
      if (enc_utf8 || STRCMP(p_enc, "latin1") == 0
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 687,770 ****
Karsten Hopp 5e4d4a
      {
Karsten Hopp 5e4d4a
  	switch (c)
Karsten Hopp 5e4d4a
  	{
Karsten Hopp 5e4d4a
! 	    case 'A': case '\300': case '\301': case '\302':
Karsten Hopp 5e4d4a
! 	    case '\303': case '\304': case '\305':
Karsten Hopp 5e4d4a
! 		    EMIT2('A');	    EMIT2('\300');  EMIT2('\301');
Karsten Hopp 5e4d4a
! 		    EMIT2('\302');  EMIT2('\303');  EMIT2('\304');
Karsten Hopp 5e4d4a
! 		    EMIT2('\305');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'C': case '\307':
Karsten Hopp 5e4d4a
! 		    EMIT2('C');	    EMIT2('\307');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'E': case '\310': case '\311': case '\312': case '\313':
Karsten Hopp 5e4d4a
! 		    EMIT2('E');	    EMIT2('\310');  EMIT2('\311');
Karsten Hopp 5e4d4a
! 		    EMIT2('\312');  EMIT2('\313');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'I': case '\314': case '\315': case '\316': case '\317':
Karsten Hopp 5e4d4a
! 		    EMIT2('I');	    EMIT2('\314');  EMIT2('\315');
Karsten Hopp 5e4d4a
! 		    EMIT2('\316');  EMIT2('\317');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'N': case '\321':
Karsten Hopp 5e4d4a
! 		    EMIT2('N');	    EMIT2('\321');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'O': case '\322': case '\323': case '\324': case '\325':
Karsten Hopp 5e4d4a
! 	    case '\326':
Karsten Hopp 5e4d4a
! 		    EMIT2('O');	    EMIT2('\322');  EMIT2('\323');
Karsten Hopp 5e4d4a
! 		    EMIT2('\324');  EMIT2('\325');  EMIT2('\326');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'U': case '\331': case '\332': case '\333': case '\334':
Karsten Hopp 5e4d4a
! 		    EMIT2('U');	    EMIT2('\331');  EMIT2('\332');
Karsten Hopp 5e4d4a
! 		    EMIT2('\333');  EMIT2('\334');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'Y': case '\335':
Karsten Hopp 5e4d4a
! 		    EMIT2('Y');	    EMIT2('\335');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'a': case '\340': case '\341': case '\342':
Karsten Hopp 5e4d4a
! 	    case '\343': case '\344': case '\345':
Karsten Hopp 5e4d4a
! 		    EMIT2('a');	    EMIT2('\340');  EMIT2('\341');
Karsten Hopp 5e4d4a
! 		    EMIT2('\342');  EMIT2('\343');  EMIT2('\344');
Karsten Hopp 5e4d4a
! 		    EMIT2('\345');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'c': case '\347':
Karsten Hopp 5e4d4a
! 		    EMIT2('c');	    EMIT2('\347');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'e': case '\350': case '\351': case '\352': case '\353':
Karsten Hopp 5e4d4a
! 		    EMIT2('e');	    EMIT2('\350');  EMIT2('\351');
Karsten Hopp 5e4d4a
! 		    EMIT2('\352');  EMIT2('\353');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'i': case '\354': case '\355': case '\356': case '\357':
Karsten Hopp 5e4d4a
! 		    EMIT2('i');	    EMIT2('\354');  EMIT2('\355');
Karsten Hopp 5e4d4a
! 		    EMIT2('\356');  EMIT2('\357');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'n': case '\361':
Karsten Hopp 5e4d4a
! 		    EMIT2('n');	    EMIT2('\361');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'o': case '\362': case '\363': case '\364': case '\365':
Karsten Hopp 5e4d4a
! 	    case '\366':
Karsten Hopp 5e4d4a
! 		    EMIT2('o');	    EMIT2('\362');  EMIT2('\363');
Karsten Hopp 5e4d4a
! 		    EMIT2('\364');  EMIT2('\365');  EMIT2('\366');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'u': case '\371': case '\372': case '\373': case '\374':
Karsten Hopp 5e4d4a
! 		    EMIT2('u');	    EMIT2('\371');  EMIT2('\372');
Karsten Hopp 5e4d4a
! 		    EMIT2('\373');  EMIT2('\374');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'y': case '\375': case '\377':
Karsten Hopp 5e4d4a
! 		    EMIT2('y');	    EMIT2('\375');  EMIT2('\377');
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  	    default:
Karsten Hopp 5e4d4a
--- 684,767 ----
Karsten Hopp 5e4d4a
      {
Karsten Hopp 5e4d4a
  	switch (c)
Karsten Hopp 5e4d4a
  	{
Karsten Hopp 5e4d4a
! 	    case 'A': case 0300: case 0301: case 0302:
Karsten Hopp 5e4d4a
! 	    case 0303: case 0304: case 0305:
Karsten Hopp 5e4d4a
! 		    EMIT2('A');	    EMIT2(0300);  EMIT2(0301);
Karsten Hopp 5e4d4a
! 		    EMIT2(0302);  EMIT2(0303);  EMIT2(0304);
Karsten Hopp 5e4d4a
! 		    EMIT2(0305);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'C': case 0307:
Karsten Hopp 5e4d4a
! 		    EMIT2('C');	    EMIT2(0307);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'E': case 0310: case 0311: case 0312: case 0313:
Karsten Hopp 5e4d4a
! 		    EMIT2('E');	    EMIT2(0310);  EMIT2(0311);
Karsten Hopp 5e4d4a
! 		    EMIT2(0312);  EMIT2(0313);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'I': case 0314: case 0315: case 0316: case 0317:
Karsten Hopp 5e4d4a
! 		    EMIT2('I');	    EMIT2(0314);  EMIT2(0315);
Karsten Hopp 5e4d4a
! 		    EMIT2(0316);  EMIT2(0317);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'N': case 0321:
Karsten Hopp 5e4d4a
! 		    EMIT2('N');	    EMIT2(0321);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'O': case 0322: case 0323: case 0324: case 0325:
Karsten Hopp 5e4d4a
! 	    case 0326:
Karsten Hopp 5e4d4a
! 		    EMIT2('O');	    EMIT2(0322);  EMIT2(0323);
Karsten Hopp 5e4d4a
! 		    EMIT2(0324);  EMIT2(0325);  EMIT2(0326);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'U': case 0331: case 0332: case 0333: case 0334:
Karsten Hopp 5e4d4a
! 		    EMIT2('U');	    EMIT2(0331);  EMIT2(0332);
Karsten Hopp 5e4d4a
! 		    EMIT2(0333);  EMIT2(0334);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'Y': case 0335:
Karsten Hopp 5e4d4a
! 		    EMIT2('Y');	    EMIT2(0335);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'a': case 0340: case 0341: case 0342:
Karsten Hopp 5e4d4a
! 	    case 0343: case 0344: case 0345:
Karsten Hopp 5e4d4a
! 		    EMIT2('a');	    EMIT2(0340);  EMIT2(0341);
Karsten Hopp 5e4d4a
! 		    EMIT2(0342);  EMIT2(0343);  EMIT2(0344);
Karsten Hopp 5e4d4a
! 		    EMIT2(0345);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'c': case 0347:
Karsten Hopp 5e4d4a
! 		    EMIT2('c');	    EMIT2(0347);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'e': case 0350: case 0351: case 0352: case 0353:
Karsten Hopp 5e4d4a
! 		    EMIT2('e');	    EMIT2(0350);  EMIT2(0351);
Karsten Hopp 5e4d4a
! 		    EMIT2(0352);  EMIT2(0353);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'i': case 0354: case 0355: case 0356: case 0357:
Karsten Hopp 5e4d4a
! 		    EMIT2('i');	    EMIT2(0354);  EMIT2(0355);
Karsten Hopp 5e4d4a
! 		    EMIT2(0356);  EMIT2(0357);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'n': case 0361:
Karsten Hopp 5e4d4a
! 		    EMIT2('n');	    EMIT2(0361);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'o': case 0362: case 0363: case 0364: case 0365:
Karsten Hopp 5e4d4a
! 	    case 0366:
Karsten Hopp 5e4d4a
! 		    EMIT2('o');	    EMIT2(0362);  EMIT2(0363);
Karsten Hopp 5e4d4a
! 		    EMIT2(0364);  EMIT2(0365);  EMIT2(0366);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'u': case 0371: case 0372: case 0373: case 0374:
Karsten Hopp 5e4d4a
! 		    EMIT2('u');	    EMIT2(0371);  EMIT2(0372);
Karsten Hopp 5e4d4a
! 		    EMIT2(0373);  EMIT2(0374);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case 'y': case 0375: case 0377:
Karsten Hopp 5e4d4a
! 		    EMIT2('y');	    EMIT2(0375);  EMIT2(0377);
Karsten Hopp 5e4d4a
  		    return OK;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  	    default:
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 811,824 ****
Karsten Hopp 5e4d4a
      char_u	*old_regparse = regparse;
Karsten Hopp 5e4d4a
  #endif
Karsten Hopp 5e4d4a
      int		extra = 0;
Karsten Hopp 5e4d4a
-     int		first;
Karsten Hopp 5e4d4a
      int		emit_range;
Karsten Hopp 5e4d4a
      int		negated;
Karsten Hopp 5e4d4a
      int		result;
Karsten Hopp 5e4d4a
      int		startc = -1;
Karsten Hopp 5e4d4a
      int		endc = -1;
Karsten Hopp 5e4d4a
      int		oldstartc = -1;
Karsten Hopp 5e4d4a
-     int		glue;		/* ID that will "glue" nodes together */
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
      c = getchr();
Karsten Hopp 5e4d4a
      switch (c)
Karsten Hopp 5e4d4a
--- 808,819 ----
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 927,934 ****
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  	case Magic('n'):
Karsten Hopp 5e4d4a
  	    if (reg_string)
Karsten Hopp 5e4d4a
! 	    /* In a string "\n" matches a newline character. */
Karsten Hopp 5e4d4a
! 	    EMIT(NL);
Karsten Hopp 5e4d4a
  	    else
Karsten Hopp 5e4d4a
  	    {
Karsten Hopp 5e4d4a
  		/* In buffer text "\n" matches the end of a line. */
Karsten Hopp 5e4d4a
--- 922,929 ----
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  	case Magic('n'):
Karsten Hopp 5e4d4a
  	    if (reg_string)
Karsten Hopp 5e4d4a
! 		/* In a string "\n" matches a newline character. */
Karsten Hopp 5e4d4a
! 		EMIT(NL);
Karsten Hopp 5e4d4a
  	    else
Karsten Hopp 5e4d4a
  	    {
Karsten Hopp 5e4d4a
  		/* In buffer text "\n" matches the end of a line. */
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 1160,1191 ****
Karsten Hopp 5e4d4a
  	case Magic('['):
Karsten Hopp 5e4d4a
  collection:
Karsten Hopp 5e4d4a
  	    /*
Karsten Hopp 5e4d4a
! 	     * Glue is emitted between several atoms from the [].
Karsten Hopp 5e4d4a
! 	     * It is either NFA_OR, or NFA_CONCAT.
Karsten Hopp 5e4d4a
! 	     *
Karsten Hopp 5e4d4a
! 	     * [abc] expands to 'a b NFA_OR c NFA_OR' (in postfix notation)
Karsten Hopp 5e4d4a
! 	     * [^abc] expands to 'a NFA_NOT b NFA_NOT NFA_CONCAT c NFA_NOT
Karsten Hopp 5e4d4a
! 	     *		NFA_CONCAT NFA_END_NEG_RANGE NFA_CONCAT' (in postfix
Karsten Hopp 5e4d4a
! 	     *		notation)
Karsten Hopp 5e4d4a
! 	     *
Karsten Hopp 5e4d4a
  	     */
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
- 
Karsten Hopp 5e4d4a
- /* Emit negation atoms, if needed.
Karsten Hopp 5e4d4a
-  * The CONCAT below merges the NOT with the previous node. */
Karsten Hopp 5e4d4a
- #define TRY_NEG()		    \
Karsten Hopp 5e4d4a
- 	    if (negated == TRUE)    \
Karsten Hopp 5e4d4a
- 	    {			    \
Karsten Hopp 5e4d4a
- 		EMIT(NFA_NOT);	    \
Karsten Hopp 5e4d4a
- 	    }
Karsten Hopp 5e4d4a
- 
Karsten Hopp 5e4d4a
- /* Emit glue between important nodes : CONCAT or OR. */
Karsten Hopp 5e4d4a
- #define EMIT_GLUE()		    \
Karsten Hopp 5e4d4a
- 	    if (first == FALSE)	    \
Karsten Hopp 5e4d4a
- 		EMIT(glue);	    \
Karsten Hopp 5e4d4a
- 	    else		    \
Karsten Hopp 5e4d4a
- 		first = FALSE;
Karsten Hopp 5e4d4a
- 
Karsten Hopp 5e4d4a
  	    p = regparse;
Karsten Hopp 5e4d4a
  	    endp = skip_anyof(p);
Karsten Hopp 5e4d4a
  	    if (*endp == ']')
Karsten Hopp 5e4d4a
--- 1155,1169 ----
Karsten Hopp 5e4d4a
  	case Magic('['):
Karsten Hopp 5e4d4a
  collection:
Karsten Hopp 5e4d4a
  	    /*
Karsten Hopp 5e4d4a
! 	     * [abc]  uses NFA_START_COLL - NFA_END_COLL
Karsten Hopp 5e4d4a
! 	     * [^abc] uses NFA_START_NEG_COLL - NFA_END_NEG_COLL
Karsten Hopp 5e4d4a
! 	     * Each character is produced as a regular state, using
Karsten Hopp 5e4d4a
! 	     * NFA_CONCAT to bind them together.
Karsten Hopp 5e4d4a
! 	     * Besides normal characters there can be:
Karsten Hopp 5e4d4a
! 	     * - character classes  NFA_CLASS_*
Karsten Hopp 5e4d4a
! 	     * - ranges, two characters followed by NFA_RANGE.
Karsten Hopp 5e4d4a
  	     */
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  	    p = regparse;
Karsten Hopp 5e4d4a
  	    endp = skip_anyof(p);
Karsten Hopp 5e4d4a
  	    if (*endp == ']')
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 1216,1236 ****
Karsten Hopp 5e4d4a
  		 * version that turns [abc] into 'a' OR 'b' OR 'c'
Karsten Hopp 5e4d4a
  		 */
Karsten Hopp 5e4d4a
  		startc = endc = oldstartc = -1;
Karsten Hopp 5e4d4a
- 		first = TRUE;	    /* Emitting first atom in this sequence? */
Karsten Hopp 5e4d4a
  		negated = FALSE;
Karsten Hopp 5e4d4a
- 		glue = NFA_OR;
Karsten Hopp 5e4d4a
  		if (*regparse == '^')			/* negated range */
Karsten Hopp 5e4d4a
  		{
Karsten Hopp 5e4d4a
  		    negated = TRUE;
Karsten Hopp 5e4d4a
- 		    glue = NFA_CONCAT;
Karsten Hopp 5e4d4a
  		    mb_ptr_adv(regparse);
Karsten Hopp 5e4d4a
  		}
Karsten Hopp 5e4d4a
  		if (*regparse == '-')
Karsten Hopp 5e4d4a
  		{
Karsten Hopp 5e4d4a
  		    startc = '-';
Karsten Hopp 5e4d4a
  		    EMIT(startc);
Karsten Hopp 5e4d4a
! 		    TRY_NEG();
Karsten Hopp 5e4d4a
! 		    EMIT_GLUE();
Karsten Hopp 5e4d4a
  		    mb_ptr_adv(regparse);
Karsten Hopp 5e4d4a
  		}
Karsten Hopp 5e4d4a
  		/* Emit the OR branches for each character in the [] */
Karsten Hopp 5e4d4a
--- 1194,1213 ----
Karsten Hopp 5e4d4a
  		 * version that turns [abc] into 'a' OR 'b' OR 'c'
Karsten Hopp 5e4d4a
  		 */
Karsten Hopp 5e4d4a
  		startc = endc = oldstartc = -1;
Karsten Hopp 5e4d4a
  		negated = FALSE;
Karsten Hopp 5e4d4a
  		if (*regparse == '^')			/* negated range */
Karsten Hopp 5e4d4a
  		{
Karsten Hopp 5e4d4a
  		    negated = TRUE;
Karsten Hopp 5e4d4a
  		    mb_ptr_adv(regparse);
Karsten Hopp 5e4d4a
+ 		    EMIT(NFA_START_NEG_COLL);
Karsten Hopp 5e4d4a
  		}
Karsten Hopp 5e4d4a
+ 		else
Karsten Hopp 5e4d4a
+ 		    EMIT(NFA_START_COLL);
Karsten Hopp 5e4d4a
  		if (*regparse == '-')
Karsten Hopp 5e4d4a
  		{
Karsten Hopp 5e4d4a
  		    startc = '-';
Karsten Hopp 5e4d4a
  		    EMIT(startc);
Karsten Hopp 5e4d4a
! 		    EMIT(NFA_CONCAT);
Karsten Hopp 5e4d4a
  		    mb_ptr_adv(regparse);
Karsten Hopp 5e4d4a
  		}
Karsten Hopp 5e4d4a
  		/* Emit the OR branches for each character in the [] */
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 1306,1325 ****
Karsten Hopp 5e4d4a
  				    EMIT(NFA_CLASS_ESCAPE);
Karsten Hopp 5e4d4a
  				    break;
Karsten Hopp 5e4d4a
  			    }
Karsten Hopp 5e4d4a
! 			    TRY_NEG();
Karsten Hopp 5e4d4a
! 			    EMIT_GLUE();
Karsten Hopp 5e4d4a
  			    continue;
Karsten Hopp 5e4d4a
  			}
Karsten Hopp 5e4d4a
  			/* Try equivalence class [=a=] and the like */
Karsten Hopp 5e4d4a
  			if (equiclass != 0)
Karsten Hopp 5e4d4a
  			{
Karsten Hopp 5e4d4a
! 			    result = nfa_emit_equi_class(equiclass, negated);
Karsten Hopp 5e4d4a
  			    if (result == FAIL)
Karsten Hopp 5e4d4a
  			    {
Karsten Hopp 5e4d4a
  				/* should never happen */
Karsten Hopp 5e4d4a
  				EMSG_RET_FAIL(_("E868: Error building NFA with equivalence class!"));
Karsten Hopp 5e4d4a
  			    }
Karsten Hopp 5e4d4a
- 			    EMIT_GLUE();
Karsten Hopp 5e4d4a
  			    continue;
Karsten Hopp 5e4d4a
  			}
Karsten Hopp 5e4d4a
  			/* Try collating class like [. .]  */
Karsten Hopp 5e4d4a
--- 1283,1300 ----
Karsten Hopp 5e4d4a
  				    EMIT(NFA_CLASS_ESCAPE);
Karsten Hopp 5e4d4a
  				    break;
Karsten Hopp 5e4d4a
  			    }
Karsten Hopp 5e4d4a
! 			    EMIT(NFA_CONCAT);
Karsten Hopp 5e4d4a
  			    continue;
Karsten Hopp 5e4d4a
  			}
Karsten Hopp 5e4d4a
  			/* Try equivalence class [=a=] and the like */
Karsten Hopp 5e4d4a
  			if (equiclass != 0)
Karsten Hopp 5e4d4a
  			{
Karsten Hopp 5e4d4a
! 			    result = nfa_emit_equi_class(equiclass);
Karsten Hopp 5e4d4a
  			    if (result == FAIL)
Karsten Hopp 5e4d4a
  			    {
Karsten Hopp 5e4d4a
  				/* should never happen */
Karsten Hopp 5e4d4a
  				EMSG_RET_FAIL(_("E868: Error building NFA with equivalence class!"));
Karsten Hopp 5e4d4a
  			    }
Karsten Hopp 5e4d4a
  			    continue;
Karsten Hopp 5e4d4a
  			}
Karsten Hopp 5e4d4a
  			/* Try collating class like [. .]  */
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 1391,1409 ****
Karsten Hopp 5e4d4a
  			startc = oldstartc;
Karsten Hopp 5e4d4a
  			if (startc > endc)
Karsten Hopp 5e4d4a
  			    EMSG_RET_FAIL(_(e_invrange));
Karsten Hopp 5e4d4a
  #ifdef FEAT_MBYTE
Karsten Hopp 5e4d4a
! 			if (has_mbyte && ((*mb_char2len)(startc) > 1
Karsten Hopp 5e4d4a
  				    || (*mb_char2len)(endc) > 1))
Karsten Hopp 5e4d4a
  			{
Karsten Hopp 5e4d4a
! 			    if (endc > startc + 256)
Karsten Hopp 5e4d4a
! 				EMSG_RET_FAIL(_(e_invrange));
Karsten Hopp 5e4d4a
! 			    /* Emit the range. "startc" was already emitted, so
Karsten Hopp 5e4d4a
! 			     * skip it. */
Karsten Hopp 5e4d4a
  			    for (c = startc + 1; c <= endc; c++)
Karsten Hopp 5e4d4a
  			    {
Karsten Hopp 5e4d4a
  				EMIT(c);
Karsten Hopp 5e4d4a
! 				TRY_NEG();
Karsten Hopp 5e4d4a
! 				EMIT_GLUE();
Karsten Hopp 5e4d4a
  			    }
Karsten Hopp 5e4d4a
  			}
Karsten Hopp 5e4d4a
  			else
Karsten Hopp 5e4d4a
--- 1366,1397 ----
Karsten Hopp 5e4d4a
  			startc = oldstartc;
Karsten Hopp 5e4d4a
  			if (startc > endc)
Karsten Hopp 5e4d4a
  			    EMSG_RET_FAIL(_(e_invrange));
Karsten Hopp 5e4d4a
+ 
Karsten Hopp 5e4d4a
+ 			if (endc > startc + 2)
Karsten Hopp 5e4d4a
+ 			{
Karsten Hopp 5e4d4a
+ 			    /* Emit a range instead of the sequence of
Karsten Hopp 5e4d4a
+ 			     * individual characters. */
Karsten Hopp 5e4d4a
+ 			    if (startc == 0)
Karsten Hopp 5e4d4a
+ 				/* \x00 is translated to \x0a, start at \x01. */
Karsten Hopp 5e4d4a
+ 				EMIT(1);
Karsten Hopp 5e4d4a
+ 			    else
Karsten Hopp 5e4d4a
+ 				--post_ptr; /* remove NFA_CONCAT */
Karsten Hopp 5e4d4a
+ 			    EMIT(endc);
Karsten Hopp 5e4d4a
+ 			    EMIT(NFA_RANGE);
Karsten Hopp 5e4d4a
+ 			    EMIT(NFA_CONCAT);
Karsten Hopp 5e4d4a
+ 			}
Karsten Hopp 5e4d4a
+ 			else
Karsten Hopp 5e4d4a
  #ifdef FEAT_MBYTE
Karsten Hopp 5e4d4a
! 			     if (has_mbyte && ((*mb_char2len)(startc) > 1
Karsten Hopp 5e4d4a
  				    || (*mb_char2len)(endc) > 1))
Karsten Hopp 5e4d4a
  			{
Karsten Hopp 5e4d4a
! 			    /* Emit the characters in the range.
Karsten Hopp 5e4d4a
! 			     * "startc" was already emitted, so skip it.
Karsten Hopp 5e4d4a
! 			     * */
Karsten Hopp 5e4d4a
  			    for (c = startc + 1; c <= endc; c++)
Karsten Hopp 5e4d4a
  			    {
Karsten Hopp 5e4d4a
  				EMIT(c);
Karsten Hopp 5e4d4a
! 				EMIT(NFA_CONCAT);
Karsten Hopp 5e4d4a
  			    }
Karsten Hopp 5e4d4a
  			}
Karsten Hopp 5e4d4a
  			else
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 1425,1432 ****
Karsten Hopp 5e4d4a
  #endif
Karsten Hopp 5e4d4a
  				{
Karsten Hopp 5e4d4a
  				    EMIT(c);
Karsten Hopp 5e4d4a
! 				    TRY_NEG();
Karsten Hopp 5e4d4a
! 				    EMIT_GLUE();
Karsten Hopp 5e4d4a
  				}
Karsten Hopp 5e4d4a
  			}
Karsten Hopp 5e4d4a
  			emit_range = FALSE;
Karsten Hopp 5e4d4a
--- 1413,1419 ----
Karsten Hopp 5e4d4a
  #endif
Karsten Hopp 5e4d4a
  				{
Karsten Hopp 5e4d4a
  				    EMIT(c);
Karsten Hopp 5e4d4a
! 				    EMIT(NFA_CONCAT);
Karsten Hopp 5e4d4a
  				}
Karsten Hopp 5e4d4a
  			}
Karsten Hopp 5e4d4a
  			emit_range = FALSE;
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 1434,1456 ****
Karsten Hopp 5e4d4a
  		    }
Karsten Hopp 5e4d4a
  		    else
Karsten Hopp 5e4d4a
  		    {
Karsten Hopp 5e4d4a
! 			/*
Karsten Hopp 5e4d4a
! 			 * This char (startc) is not part of a range. Just
Karsten Hopp 5e4d4a
  			 * emit it.
Karsten Hopp 5e4d4a
- 			 *
Karsten Hopp 5e4d4a
  			 * Normally, simply emit startc. But if we get char
Karsten Hopp 5e4d4a
  			 * code=0 from a collating char, then replace it with
Karsten Hopp 5e4d4a
  			 * 0x0a.
Karsten Hopp 5e4d4a
- 			 *
Karsten Hopp 5e4d4a
  			 * This is needed to completely mimic the behaviour of
Karsten Hopp 5e4d4a
! 			 * the backtracking engine.
Karsten Hopp 5e4d4a
! 			 */
Karsten Hopp 5e4d4a
! 			if (got_coll_char == TRUE && startc == 0)
Karsten Hopp 5e4d4a
! 			    EMIT(0x0a);
Karsten Hopp 5e4d4a
  			else
Karsten Hopp 5e4d4a
! 			    EMIT(startc);
Karsten Hopp 5e4d4a
! 			TRY_NEG();
Karsten Hopp 5e4d4a
! 			EMIT_GLUE();
Karsten Hopp 5e4d4a
  		    }
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  		    mb_ptr_adv(regparse);
Karsten Hopp 5e4d4a
--- 1421,1449 ----
Karsten Hopp 5e4d4a
  		    }
Karsten Hopp 5e4d4a
  		    else
Karsten Hopp 5e4d4a
  		    {
Karsten Hopp 5e4d4a
! 			/* This char (startc) is not part of a range. Just
Karsten Hopp 5e4d4a
  			 * emit it.
Karsten Hopp 5e4d4a
  			 * Normally, simply emit startc. But if we get char
Karsten Hopp 5e4d4a
  			 * code=0 from a collating char, then replace it with
Karsten Hopp 5e4d4a
  			 * 0x0a.
Karsten Hopp 5e4d4a
  			 * This is needed to completely mimic the behaviour of
Karsten Hopp 5e4d4a
! 			 * the backtracking engine. */
Karsten Hopp 5e4d4a
! 			if (startc == NFA_NEWL)
Karsten Hopp 5e4d4a
! 			{
Karsten Hopp 5e4d4a
! 			    /* Line break can't be matched as part of the
Karsten Hopp 5e4d4a
! 			     * collection, add an OR below. But not for negated
Karsten Hopp 5e4d4a
! 			     * range. */
Karsten Hopp 5e4d4a
! 			    if (!negated)
Karsten Hopp 5e4d4a
! 				extra = ADD_NL;
Karsten Hopp 5e4d4a
! 			}
Karsten Hopp 5e4d4a
  			else
Karsten Hopp 5e4d4a
! 			{
Karsten Hopp 5e4d4a
! 			    if (got_coll_char == TRUE && startc == 0)
Karsten Hopp 5e4d4a
! 				EMIT(0x0a);
Karsten Hopp 5e4d4a
! 			    else
Karsten Hopp 5e4d4a
! 				EMIT(startc);
Karsten Hopp 5e4d4a
! 			    EMIT(NFA_CONCAT);
Karsten Hopp 5e4d4a
! 			}
Karsten Hopp 5e4d4a
  		    }
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  		    mb_ptr_adv(regparse);
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 1460,1479 ****
Karsten Hopp 5e4d4a
  		if (*regparse == '-')	    /* if last, '-' is just a char */
Karsten Hopp 5e4d4a
  		{
Karsten Hopp 5e4d4a
  		    EMIT('-');
Karsten Hopp 5e4d4a
! 		    TRY_NEG();
Karsten Hopp 5e4d4a
! 		    EMIT_GLUE();
Karsten Hopp 5e4d4a
  		}
Karsten Hopp 5e4d4a
  		mb_ptr_adv(regparse);
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  		/* skip the trailing ] */
Karsten Hopp 5e4d4a
  		regparse = endp;
Karsten Hopp 5e4d4a
  		mb_ptr_adv(regparse);
Karsten Hopp 5e4d4a
  		if (negated == TRUE)
Karsten Hopp 5e4d4a
! 		{
Karsten Hopp 5e4d4a
! 		    /* Mark end of negated char range */
Karsten Hopp 5e4d4a
! 		    EMIT(NFA_END_NEG_RANGE);
Karsten Hopp 5e4d4a
! 		    EMIT(NFA_CONCAT);
Karsten Hopp 5e4d4a
! 		}
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  		/* \_[] also matches \n but it's not negated */
Karsten Hopp 5e4d4a
  		if (extra == ADD_NL)
Karsten Hopp 5e4d4a
--- 1453,1471 ----
Karsten Hopp 5e4d4a
  		if (*regparse == '-')	    /* if last, '-' is just a char */
Karsten Hopp 5e4d4a
  		{
Karsten Hopp 5e4d4a
  		    EMIT('-');
Karsten Hopp 5e4d4a
! 		    EMIT(NFA_CONCAT);
Karsten Hopp 5e4d4a
  		}
Karsten Hopp 5e4d4a
  		mb_ptr_adv(regparse);
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  		/* skip the trailing ] */
Karsten Hopp 5e4d4a
  		regparse = endp;
Karsten Hopp 5e4d4a
  		mb_ptr_adv(regparse);
Karsten Hopp 5e4d4a
+ 
Karsten Hopp 5e4d4a
+ 		/* Mark end of the collection. */
Karsten Hopp 5e4d4a
  		if (negated == TRUE)
Karsten Hopp 5e4d4a
! 		    EMIT(NFA_END_NEG_COLL);
Karsten Hopp 5e4d4a
! 		else
Karsten Hopp 5e4d4a
! 		    EMIT(NFA_END_COLL);
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  		/* \_[] also matches \n but it's not negated */
Karsten Hopp 5e4d4a
  		if (extra == ADD_NL)
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 1532,1540 ****
Karsten Hopp 5e4d4a
  	    }
Karsten Hopp 5e4d4a
      }
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
- #undef TRY_NEG
Karsten Hopp 5e4d4a
- #undef EMIT_GLUE
Karsten Hopp 5e4d4a
- 
Karsten Hopp 5e4d4a
      return OK;
Karsten Hopp 5e4d4a
  }
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
--- 1524,1529 ----
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 2091,2100 ****
Karsten Hopp 5e4d4a
  	case NFA_STAR_NONGREEDY: STRCPY(code, "NFA_STAR_NONGREEDY "); break;
Karsten Hopp 5e4d4a
  	case NFA_QUEST:		STRCPY(code, "NFA_QUEST"); break;
Karsten Hopp 5e4d4a
  	case NFA_QUEST_NONGREEDY: STRCPY(code, "NFA_QUEST_NON_GREEDY"); break;
Karsten Hopp 5e4d4a
- 	case NFA_NOT:		STRCPY(code, "NFA_NOT "); break;
Karsten Hopp 5e4d4a
  	case NFA_SKIP_CHAR:	STRCPY(code, "NFA_SKIP_CHAR"); break;
Karsten Hopp 5e4d4a
  	case NFA_OR:		STRCPY(code, "NFA_OR"); break;
Karsten Hopp 5e4d4a
! 	case NFA_END_NEG_RANGE:	STRCPY(code, "NFA_END_NEG_RANGE"); break;
Karsten Hopp 5e4d4a
  	case NFA_CLASS_ALNUM:	STRCPY(code, "NFA_CLASS_ALNUM"); break;
Karsten Hopp 5e4d4a
  	case NFA_CLASS_ALPHA:	STRCPY(code, "NFA_CLASS_ALPHA"); break;
Karsten Hopp 5e4d4a
  	case NFA_CLASS_BLANK:	STRCPY(code, "NFA_CLASS_BLANK"); break;
Karsten Hopp 5e4d4a
--- 2080,2096 ----
Karsten Hopp 5e4d4a
  	case NFA_STAR_NONGREEDY: STRCPY(code, "NFA_STAR_NONGREEDY "); break;
Karsten Hopp 5e4d4a
  	case NFA_QUEST:		STRCPY(code, "NFA_QUEST"); break;
Karsten Hopp 5e4d4a
  	case NFA_QUEST_NONGREEDY: STRCPY(code, "NFA_QUEST_NON_GREEDY"); break;
Karsten Hopp 5e4d4a
  	case NFA_SKIP_CHAR:	STRCPY(code, "NFA_SKIP_CHAR"); break;
Karsten Hopp 5e4d4a
  	case NFA_OR:		STRCPY(code, "NFA_OR"); break;
Karsten Hopp 5e4d4a
! 
Karsten Hopp 5e4d4a
! 	case NFA_START_COLL:	STRCPY(code, "NFA_START_COLL"); break;
Karsten Hopp 5e4d4a
! 	case NFA_END_COLL:	STRCPY(code, "NFA_END_COLL"); break;
Karsten Hopp 5e4d4a
! 	case NFA_START_NEG_COLL: STRCPY(code, "NFA_START_NEG_COLL"); break;
Karsten Hopp 5e4d4a
! 	case NFA_END_NEG_COLL:	STRCPY(code, "NFA_END_NEG_COLL"); break;
Karsten Hopp 5e4d4a
! 	case NFA_RANGE:		STRCPY(code, "NFA_RANGE"); break;
Karsten Hopp 5e4d4a
! 	case NFA_RANGE_MIN:	STRCPY(code, "NFA_RANGE_MIN"); break;
Karsten Hopp 5e4d4a
! 	case NFA_RANGE_MAX:	STRCPY(code, "NFA_RANGE_MAX"); break;
Karsten Hopp 5e4d4a
! 
Karsten Hopp 5e4d4a
  	case NFA_CLASS_ALNUM:	STRCPY(code, "NFA_CLASS_ALNUM"); break;
Karsten Hopp 5e4d4a
  	case NFA_CLASS_ALPHA:	STRCPY(code, "NFA_CLASS_ALPHA"); break;
Karsten Hopp 5e4d4a
  	case NFA_CLASS_BLANK:	STRCPY(code, "NFA_CLASS_BLANK"); break;
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 2231,2238 ****
Karsten Hopp 5e4d4a
  	fprintf(debugf, " %s", p);
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
      nfa_set_code(state->c);
Karsten Hopp 5e4d4a
!     fprintf(debugf, "%s%s (%d) (id=%d)\n",
Karsten Hopp 5e4d4a
! 		 state->negated ? "NOT " : "", code, state->c, abs(state->id));
Karsten Hopp 5e4d4a
      if (state->id < 0)
Karsten Hopp 5e4d4a
  	return;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
--- 2227,2238 ----
Karsten Hopp 5e4d4a
  	fprintf(debugf, " %s", p);
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
      nfa_set_code(state->c);
Karsten Hopp 5e4d4a
!     fprintf(debugf, "%s%s (%d) (id=%d) val=%d\n",
Karsten Hopp 5e4d4a
! 		 state->negated ? "NOT " : "",
Karsten Hopp 5e4d4a
! 		 code,
Karsten Hopp 5e4d4a
! 		 state->c,
Karsten Hopp 5e4d4a
! 		 abs(state->id),
Karsten Hopp 5e4d4a
! 		 state->val);
Karsten Hopp 5e4d4a
      if (state->id < 0)
Karsten Hopp 5e4d4a
  	return;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 2325,2330 ****
Karsten Hopp 5e4d4a
--- 2325,2331 ----
Karsten Hopp 5e4d4a
      s->c    = c;
Karsten Hopp 5e4d4a
      s->out  = out;
Karsten Hopp 5e4d4a
      s->out1 = out1;
Karsten Hopp 5e4d4a
+     s->val  = 0;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
      s->id   = istate;
Karsten Hopp 5e4d4a
      s->lastlist[0] = 0;
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 2565,2577 ****
Karsten Hopp 5e4d4a
  	switch (*p)
Karsten Hopp 5e4d4a
  	{
Karsten Hopp 5e4d4a
  	case NFA_CONCAT:
Karsten Hopp 5e4d4a
! 	    /* Catenation.
Karsten Hopp 5e4d4a
! 	     * Pay attention: this operator does not exist
Karsten Hopp 5e4d4a
! 	     * in the r.e. itself (it is implicit, really).
Karsten Hopp 5e4d4a
! 	     * It is added when r.e. is translated to postfix
Karsten Hopp 5e4d4a
! 	     * form in re2post().
Karsten Hopp 5e4d4a
! 	     *
Karsten Hopp 5e4d4a
! 	     * No new state added here. */
Karsten Hopp 5e4d4a
  	    if (nfa_calc_size == TRUE)
Karsten Hopp 5e4d4a
  	    {
Karsten Hopp 5e4d4a
  		/* nstate += 0; */
Karsten Hopp 5e4d4a
--- 2566,2575 ----
Karsten Hopp 5e4d4a
  	switch (*p)
Karsten Hopp 5e4d4a
  	{
Karsten Hopp 5e4d4a
  	case NFA_CONCAT:
Karsten Hopp 5e4d4a
! 	    /* Concatenation.
Karsten Hopp 5e4d4a
! 	     * Pay attention: this operator does not exist in the r.e. itself
Karsten Hopp 5e4d4a
! 	     * (it is implicit, really).  It is added when r.e. is translated
Karsten Hopp 5e4d4a
! 	     * to postfix form in re2post(). */
Karsten Hopp 5e4d4a
  	    if (nfa_calc_size == TRUE)
Karsten Hopp 5e4d4a
  	    {
Karsten Hopp 5e4d4a
  		/* nstate += 0; */
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 2583,2604 ****
Karsten Hopp 5e4d4a
  	    PUSH(frag(e1.start, e2.out));
Karsten Hopp 5e4d4a
  	    break;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
- 	case NFA_NOT:
Karsten Hopp 5e4d4a
- 	    /* Negation of a character */
Karsten Hopp 5e4d4a
- 	    if (nfa_calc_size == TRUE)
Karsten Hopp 5e4d4a
- 	    {
Karsten Hopp 5e4d4a
- 		/* nstate += 0; */
Karsten Hopp 5e4d4a
- 		break;
Karsten Hopp 5e4d4a
- 	    }
Karsten Hopp 5e4d4a
- 	    e1 = POP();
Karsten Hopp 5e4d4a
- 	    e1.start->negated = TRUE;
Karsten Hopp 5e4d4a
- #ifdef FEAT_MBYTE
Karsten Hopp 5e4d4a
- 	    if (e1.start->c == NFA_COMPOSING)
Karsten Hopp 5e4d4a
- 		e1.start->out1->negated = TRUE;
Karsten Hopp 5e4d4a
- #endif
Karsten Hopp 5e4d4a
- 	    PUSH(e1);
Karsten Hopp 5e4d4a
- 	    break;
Karsten Hopp 5e4d4a
- 
Karsten Hopp 5e4d4a
  	case NFA_OR:
Karsten Hopp 5e4d4a
  	    /* Alternation */
Karsten Hopp 5e4d4a
  	    if (nfa_calc_size == TRUE)
Karsten Hopp 5e4d4a
--- 2581,2586 ----
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 2672,2677 ****
Karsten Hopp 5e4d4a
--- 2654,2696 ----
Karsten Hopp 5e4d4a
  	    PUSH(frag(s, append(e.out, list1(&s->out))));
Karsten Hopp 5e4d4a
  	    break;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
+ 	case NFA_END_COLL:
Karsten Hopp 5e4d4a
+ 	case NFA_END_NEG_COLL:
Karsten Hopp 5e4d4a
+ 	    /* On the stack is the sequence starting with NFA_START_COLL or
Karsten Hopp 5e4d4a
+ 	     * NFA_START_NEG_COLL and all possible characters. Patch it to
Karsten Hopp 5e4d4a
+ 	     * add the output to the start. */
Karsten Hopp 5e4d4a
+ 	    if (nfa_calc_size == TRUE)
Karsten Hopp 5e4d4a
+ 	    {
Karsten Hopp 5e4d4a
+ 		nstate++;
Karsten Hopp 5e4d4a
+ 		break;
Karsten Hopp 5e4d4a
+ 	    }
Karsten Hopp 5e4d4a
+ 	    e = POP();
Karsten Hopp 5e4d4a
+ 	    s = alloc_state(NFA_END_COLL, NULL, NULL);
Karsten Hopp 5e4d4a
+ 	    if (s == NULL)
Karsten Hopp 5e4d4a
+ 		goto theend;
Karsten Hopp 5e4d4a
+ 	    patch(e.out, s);
Karsten Hopp 5e4d4a
+ 	    e.start->out1 = s;
Karsten Hopp 5e4d4a
+ 	    PUSH(frag(e.start, list1(&s->out)));
Karsten Hopp 5e4d4a
+ 	    break;
Karsten Hopp 5e4d4a
+ 
Karsten Hopp 5e4d4a
+ 	case NFA_RANGE:
Karsten Hopp 5e4d4a
+ 	    /* Before this are two characters, the low and high end of a
Karsten Hopp 5e4d4a
+ 	     * range.  Turn them into two states with MIN and MAX. */
Karsten Hopp 5e4d4a
+ 	    if (nfa_calc_size == TRUE)
Karsten Hopp 5e4d4a
+ 	    {
Karsten Hopp 5e4d4a
+ 		/* nstate += 0; */
Karsten Hopp 5e4d4a
+ 		break;
Karsten Hopp 5e4d4a
+ 	    }
Karsten Hopp 5e4d4a
+ 	    e2 = POP();
Karsten Hopp 5e4d4a
+ 	    e1 = POP();
Karsten Hopp 5e4d4a
+ 	    e2.start->val = e2.start->c;
Karsten Hopp 5e4d4a
+ 	    e2.start->c = NFA_RANGE_MAX;
Karsten Hopp 5e4d4a
+ 	    e1.start->val = e1.start->c;
Karsten Hopp 5e4d4a
+ 	    e1.start->c = NFA_RANGE_MIN;
Karsten Hopp 5e4d4a
+ 	    patch(e1.out, e2.start);
Karsten Hopp 5e4d4a
+ 	    PUSH(frag(e1.start, e2.out));
Karsten Hopp 5e4d4a
+ 	    break;
Karsten Hopp 5e4d4a
+ 
Karsten Hopp 5e4d4a
  	case NFA_SKIP_CHAR:
Karsten Hopp 5e4d4a
  	    /* Symbol of 0-length, Used in a repetition
Karsten Hopp 5e4d4a
  	     * with max/min count of 0 */
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 2990,2995 ****
Karsten Hopp 5e4d4a
--- 3009,3016 ----
Karsten Hopp 5e4d4a
      matchstate = &state_ptr[istate++]; /* the match state */
Karsten Hopp 5e4d4a
      matchstate->c = NFA_MATCH;
Karsten Hopp 5e4d4a
      matchstate->out = matchstate->out1 = NULL;
Karsten Hopp 5e4d4a
+     matchstate->negated = FALSE;
Karsten Hopp 5e4d4a
+     matchstate->id = 0;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
      patch(e.out, matchstate);
Karsten Hopp 5e4d4a
      ret = e.start;
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 3308,3314 ****
Karsten Hopp 5e4d4a
      switch (state->c)
Karsten Hopp 5e4d4a
      {
Karsten Hopp 5e4d4a
  	case NFA_SPLIT:
Karsten Hopp 5e4d4a
- 	case NFA_NOT:
Karsten Hopp 5e4d4a
  	case NFA_NOPEN:
Karsten Hopp 5e4d4a
  	case NFA_SKIP_CHAR:
Karsten Hopp 5e4d4a
  	case NFA_NCLOSE:
Karsten Hopp 5e4d4a
--- 3329,3334 ----
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 3782,3788 ****
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  	default:
Karsten Hopp 5e4d4a
  	    /* should not be here :P */
Karsten Hopp 5e4d4a
! 	    EMSG_RET_FAIL(_("E877: (NFA regexp) Invalid character class "));
Karsten Hopp 5e4d4a
      }
Karsten Hopp 5e4d4a
      return FAIL;
Karsten Hopp 5e4d4a
  }
Karsten Hopp 5e4d4a
--- 3802,3809 ----
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  	default:
Karsten Hopp 5e4d4a
  	    /* should not be here :P */
Karsten Hopp 5e4d4a
! 	    EMSGN("E877: (NFA regexp) Invalid character class: %ld", class);
Karsten Hopp 5e4d4a
! 	    return FAIL;
Karsten Hopp 5e4d4a
      }
Karsten Hopp 5e4d4a
      return FAIL;
Karsten Hopp 5e4d4a
  }
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 4320,4327 ****
Karsten Hopp 5e4d4a
      addstate(thislist, start, m, 0);
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
      /* There are two cases when the NFA advances: 1. input char matches the
Karsten Hopp 5e4d4a
!      * NFA node and 2. input char does not match the NFA node, but the next
Karsten Hopp 5e4d4a
!      * node is NFA_NOT. The following macro calls addstate() according to
Karsten Hopp 5e4d4a
       * these rules. It is used A LOT, so use the "listtbl" table for speed */
Karsten Hopp 5e4d4a
      listtbl[0][0] = NULL;
Karsten Hopp 5e4d4a
      listtbl[0][1] = neglist;
Karsten Hopp 5e4d4a
--- 4341,4348 ----
Karsten Hopp 5e4d4a
      addstate(thislist, start, m, 0);
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
      /* There are two cases when the NFA advances: 1. input char matches the
Karsten Hopp 5e4d4a
!      * NFA node and 2. input char does not match the NFA node and the state
Karsten Hopp 5e4d4a
!      * has the negated flag. The following macro calls addstate() according to
Karsten Hopp 5e4d4a
       * these rules. It is used A LOT, so use the "listtbl" table for speed */
Karsten Hopp 5e4d4a
      listtbl[0][0] = NULL;
Karsten Hopp 5e4d4a
      listtbl[0][1] = neglist;
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 4845,4860 ****
Karsten Hopp 5e4d4a
  		ADD_POS_NEG_STATE(t->state);
Karsten Hopp 5e4d4a
  		break;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case NFA_END_NEG_RANGE:
Karsten Hopp 5e4d4a
! 		/* This follows a series of negated nodes, like:
Karsten Hopp 5e4d4a
! 		 * NOT CHAR(x), NOT CHAR(y), etc. */
Karsten Hopp 5e4d4a
! 		if (curc > 0)
Karsten Hopp 5e4d4a
  		{
Karsten Hopp 5e4d4a
  		    ll = nextlist;
Karsten Hopp 5e4d4a
! 		    add_state = t->state->out;
Karsten Hopp 5e4d4a
  		    add_off = clen;
Karsten Hopp 5e4d4a
  		}
Karsten Hopp 5e4d4a
  		break;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  	    case NFA_ANY:
Karsten Hopp 5e4d4a
  		/* Any char except '\0', (end of input) does not match. */
Karsten Hopp 5e4d4a
--- 4866,4944 ----
Karsten Hopp 5e4d4a
  		ADD_POS_NEG_STATE(t->state);
Karsten Hopp 5e4d4a
  		break;
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
! 	    case NFA_START_COLL:
Karsten Hopp 5e4d4a
! 	    case NFA_START_NEG_COLL:
Karsten Hopp 5e4d4a
! 	      {
Karsten Hopp 5e4d4a
! 		/* What follows is a list of characters, until NFA_END_COLL.
Karsten Hopp 5e4d4a
! 		 * One of them must match or none of them must match. */
Karsten Hopp 5e4d4a
! 		nfa_state_T	*state;
Karsten Hopp 5e4d4a
! 		int		result_if_matched;
Karsten Hopp 5e4d4a
! 		int		c1, c2;
Karsten Hopp 5e4d4a
! 
Karsten Hopp 5e4d4a
! 		/* Never match EOL. If it's part of the collection it is added
Karsten Hopp 5e4d4a
! 		 * as a separate state with an OR. */
Karsten Hopp 5e4d4a
! 		if (curc == NUL)
Karsten Hopp 5e4d4a
! 		    break;
Karsten Hopp 5e4d4a
! 
Karsten Hopp 5e4d4a
! 		state = t->state->out;
Karsten Hopp 5e4d4a
! 		result_if_matched = (t->state->c == NFA_START_COLL);
Karsten Hopp 5e4d4a
! 		for (;;)
Karsten Hopp 5e4d4a
  		{
Karsten Hopp 5e4d4a
+ 		    if (state->c == NFA_END_COLL)
Karsten Hopp 5e4d4a
+ 		    {
Karsten Hopp 5e4d4a
+ 			result = !result_if_matched;
Karsten Hopp 5e4d4a
+ 			break;
Karsten Hopp 5e4d4a
+ 		    }
Karsten Hopp 5e4d4a
+ 		    if (state->c == NFA_RANGE_MIN)
Karsten Hopp 5e4d4a
+ 		    {
Karsten Hopp 5e4d4a
+ 			c1 = state->val;
Karsten Hopp 5e4d4a
+ 			state = state->out; /* advance to NFA_RANGE_MAX */
Karsten Hopp 5e4d4a
+ 			c2 = state->val;
Karsten Hopp 5e4d4a
+ #ifdef ENABLE_LOG
Karsten Hopp 5e4d4a
+ 			fprintf(log_fd, "NFA_RANGE_MIN curc=%d c1=%d c2=%d\n",
Karsten Hopp 5e4d4a
+ 				curc, c1, c2);
Karsten Hopp 5e4d4a
+ #endif
Karsten Hopp 5e4d4a
+ 			if (curc >= c1 && curc <= c2)
Karsten Hopp 5e4d4a
+ 			{
Karsten Hopp 5e4d4a
+ 			    result = result_if_matched;
Karsten Hopp 5e4d4a
+ 			    break;
Karsten Hopp 5e4d4a
+ 			}
Karsten Hopp 5e4d4a
+ 			if (ireg_ic)
Karsten Hopp 5e4d4a
+ 			{
Karsten Hopp 5e4d4a
+ 			    int curc_low = MB_TOLOWER(curc);
Karsten Hopp 5e4d4a
+ 			    int done = FALSE;
Karsten Hopp 5e4d4a
+ 
Karsten Hopp 5e4d4a
+ 			    for ( ; c1 <= c2; ++c1)
Karsten Hopp 5e4d4a
+ 				if (MB_TOLOWER(c1) == curc_low)
Karsten Hopp 5e4d4a
+ 				{
Karsten Hopp 5e4d4a
+ 				    result = result_if_matched;
Karsten Hopp 5e4d4a
+ 				    done = TRUE;
Karsten Hopp 5e4d4a
+ 				    break;
Karsten Hopp 5e4d4a
+ 				}
Karsten Hopp 5e4d4a
+ 			    if (done)
Karsten Hopp 5e4d4a
+ 				break;
Karsten Hopp 5e4d4a
+ 			}
Karsten Hopp 5e4d4a
+ 		    }
Karsten Hopp 5e4d4a
+ 		    else if (state->c < 0 ? check_char_class(state->c, curc)
Karsten Hopp 5e4d4a
+ 			        : (curc == state->c
Karsten Hopp 5e4d4a
+ 				   || (ireg_ic && MB_TOLOWER(curc)
Karsten Hopp 5e4d4a
+ 						    == MB_TOLOWER(state->c))))
Karsten Hopp 5e4d4a
+ 		    {
Karsten Hopp 5e4d4a
+ 			result = result_if_matched;
Karsten Hopp 5e4d4a
+ 			break;
Karsten Hopp 5e4d4a
+ 		    }
Karsten Hopp 5e4d4a
+ 		    state = state->out;
Karsten Hopp 5e4d4a
+ 		}
Karsten Hopp 5e4d4a
+ 		if (result)
Karsten Hopp 5e4d4a
+ 		{
Karsten Hopp 5e4d4a
+ 		    /* next state is in out of the NFA_END_COLL, out1 of
Karsten Hopp 5e4d4a
+ 		     * START points to the END state */
Karsten Hopp 5e4d4a
  		    ll = nextlist;
Karsten Hopp 5e4d4a
! 		    add_state = t->state->out1->out;
Karsten Hopp 5e4d4a
  		    add_off = clen;
Karsten Hopp 5e4d4a
  		}
Karsten Hopp 5e4d4a
  		break;
Karsten Hopp 5e4d4a
+ 	      }
Karsten Hopp 5e4d4a
  
Karsten Hopp 5e4d4a
  	    case NFA_ANY:
Karsten Hopp 5e4d4a
  		/* Any char except '\0', (end of input) does not match. */
Karsten Hopp 5e4d4a
*** ../vim-7.3.1136/src/version.c	2013-06-06 21:31:02.000000000 +0200
Karsten Hopp 5e4d4a
--- src/version.c	2013-06-07 13:21:57.000000000 +0200
Karsten Hopp 5e4d4a
***************
Karsten Hopp 5e4d4a
*** 730,731 ****
Karsten Hopp 5e4d4a
--- 730,733 ----
Karsten Hopp 5e4d4a
  {   /* Add new patch number below this line */
Karsten Hopp 5e4d4a
+ /**/
Karsten Hopp 5e4d4a
+     1137,
Karsten Hopp 5e4d4a
  /**/
Karsten Hopp 5e4d4a
Karsten Hopp 5e4d4a
-- 
Karsten Hopp 5e4d4a
From "know your smileys":
Karsten Hopp 5e4d4a
 :.-(	Crying
Karsten Hopp 5e4d4a
Karsten Hopp 5e4d4a
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 5e4d4a
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 5e4d4a
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 5e4d4a
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///