home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / patches / 7.3 / 7.3.1137 < prev    next >
Encoding:
Internet Message Format  |  2013-06-06  |  26.3 KB

  1. To: vim_dev@googlegroups.com
  2. Subject: Patch 7.3.1137
  3. Fcc: outbox
  4. From: Bram Moolenaar <Bram@moolenaar.net>
  5. Mime-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. ------------
  9.  
  10. Patch 7.3.1137
  11. Problem:    New regexp engine: collections are slow.
  12. Solution:   Handle all characters in one go.
  13. Files:        src/regexp_nfa.c
  14.  
  15.  
  16. *** ../vim-7.3.1136/src/regexp_nfa.c    2013-06-06 18:46:00.000000000 +0200
  17. --- src/regexp_nfa.c    2013-06-07 13:40:58.000000000 +0200
  18. ***************
  19. *** 34,48 ****
  20.       NFA_SPLIT = -1024,
  21.       NFA_MATCH,
  22.       NFA_SKIP_CHAR,            /* matches a 0-length char */
  23. -     NFA_END_NEG_RANGE,            /* Used when expanding [^ab] */
  24.   
  25. !     NFA_CONCAT,
  26.       NFA_OR,
  27.       NFA_STAR,                /* greedy * */
  28.       NFA_STAR_NONGREEDY,            /* non-greedy * */
  29.       NFA_QUEST,                /* greedy \? */
  30.       NFA_QUEST_NONGREEDY,        /* non-greedy \? */
  31. -     NFA_NOT,                /* used for [^ab] negated char ranges */
  32.   
  33.       NFA_BOL,                /* ^    Begin line */
  34.       NFA_EOL,                /* $    End line */
  35. --- 34,56 ----
  36.       NFA_SPLIT = -1024,
  37.       NFA_MATCH,
  38.       NFA_SKIP_CHAR,            /* matches a 0-length char */
  39.   
  40. !     NFA_START_COLL,            /* [abc] start */
  41. !     NFA_END_COLL,            /* [abc] end */
  42. !     NFA_START_NEG_COLL,            /* [^abc] start */
  43. !     NFA_END_NEG_COLL,            /* [^abc] end (only used in postfix) */
  44. !     NFA_RANGE,                /* range of the two previous items (only
  45. !                      * used in postfix) */
  46. !     NFA_RANGE_MIN,            /* low end of a range  */
  47. !     NFA_RANGE_MAX,            /* high end of a range  */
  48. !     NFA_CONCAT,                /* concatenate two previous items (only
  49. !                      * used in postfix) */
  50.       NFA_OR,
  51.       NFA_STAR,                /* greedy * */
  52.       NFA_STAR_NONGREEDY,            /* non-greedy * */
  53.       NFA_QUEST,                /* greedy \? */
  54.       NFA_QUEST_NONGREEDY,        /* non-greedy \? */
  55.   
  56.       NFA_BOL,                /* ^    Begin line */
  57.       NFA_EOL,                /* $    End line */
  58. ***************
  59. *** 260,266 ****
  60.   static int nfa_get_reganch __ARGS((nfa_state_T *start, int depth));
  61.   static int nfa_get_regstart __ARGS((nfa_state_T *start, int depth));
  62.   static int nfa_recognize_char_class __ARGS((char_u *start, char_u *end, int extra_newl));
  63. ! static int nfa_emit_equi_class __ARGS((int c, int neg));
  64.   static int nfa_regatom __ARGS((void));
  65.   static int nfa_regpiece __ARGS((void));
  66.   static int nfa_regconcat __ARGS((void));
  67. --- 268,274 ----
  68.   static int nfa_get_reganch __ARGS((nfa_state_T *start, int depth));
  69.   static int nfa_get_regstart __ARGS((nfa_state_T *start, int depth));
  70.   static int nfa_recognize_char_class __ARGS((char_u *start, char_u *end, int extra_newl));
  71. ! static int nfa_emit_equi_class __ARGS((int c));
  72.   static int nfa_regatom __ARGS((void));
  73.   static int nfa_regpiece __ARGS((void));
  74.   static int nfa_regconcat __ARGS((void));
  75. ***************
  76. *** 664,684 ****
  77.    * NOTE! When changing this function, also update reg_equi_class()
  78.    */
  79.       static int
  80. ! nfa_emit_equi_class(c, neg)
  81.       int        c;
  82. -     int        neg;
  83.   {
  84. !     int    first = TRUE;
  85. !     int    glue = neg == TRUE ? NFA_CONCAT : NFA_OR;
  86. ! #define EMIT2(c)        \
  87. !     EMIT(c);        \
  88. !     if (neg == TRUE) {    \
  89. !         EMIT(NFA_NOT);    \
  90. !     }            \
  91. !     if (first == FALSE)    \
  92. !         EMIT(glue);        \
  93. !     else            \
  94. !         first = FALSE;    \
  95.   
  96.   #ifdef FEAT_MBYTE
  97.       if (enc_utf8 || STRCMP(p_enc, "latin1") == 0
  98. --- 672,681 ----
  99.    * NOTE! When changing this function, also update reg_equi_class()
  100.    */
  101.       static int
  102. ! nfa_emit_equi_class(c)
  103.       int        c;
  104.   {
  105. ! #define EMIT2(c)   EMIT(c); EMIT(NFA_CONCAT);
  106.   
  107.   #ifdef FEAT_MBYTE
  108.       if (enc_utf8 || STRCMP(p_enc, "latin1") == 0
  109. ***************
  110. *** 687,770 ****
  111.       {
  112.       switch (c)
  113.       {
  114. !         case 'A': case '\300': case '\301': case '\302':
  115. !         case '\303': case '\304': case '\305':
  116. !             EMIT2('A');        EMIT2('\300');  EMIT2('\301');
  117. !             EMIT2('\302');  EMIT2('\303');  EMIT2('\304');
  118. !             EMIT2('\305');
  119.               return OK;
  120.   
  121. !         case 'C': case '\307':
  122. !             EMIT2('C');        EMIT2('\307');
  123.               return OK;
  124.   
  125. !         case 'E': case '\310': case '\311': case '\312': case '\313':
  126. !             EMIT2('E');        EMIT2('\310');  EMIT2('\311');
  127. !             EMIT2('\312');  EMIT2('\313');
  128.               return OK;
  129.   
  130. !         case 'I': case '\314': case '\315': case '\316': case '\317':
  131. !             EMIT2('I');        EMIT2('\314');  EMIT2('\315');
  132. !             EMIT2('\316');  EMIT2('\317');
  133.               return OK;
  134.   
  135. !         case 'N': case '\321':
  136. !             EMIT2('N');        EMIT2('\321');
  137.               return OK;
  138.   
  139. !         case 'O': case '\322': case '\323': case '\324': case '\325':
  140. !         case '\326':
  141. !             EMIT2('O');        EMIT2('\322');  EMIT2('\323');
  142. !             EMIT2('\324');  EMIT2('\325');  EMIT2('\326');
  143.               return OK;
  144.   
  145. !         case 'U': case '\331': case '\332': case '\333': case '\334':
  146. !             EMIT2('U');        EMIT2('\331');  EMIT2('\332');
  147. !             EMIT2('\333');  EMIT2('\334');
  148.               return OK;
  149.   
  150. !         case 'Y': case '\335':
  151. !             EMIT2('Y');        EMIT2('\335');
  152.               return OK;
  153.   
  154. !         case 'a': case '\340': case '\341': case '\342':
  155. !         case '\343': case '\344': case '\345':
  156. !             EMIT2('a');        EMIT2('\340');  EMIT2('\341');
  157. !             EMIT2('\342');  EMIT2('\343');  EMIT2('\344');
  158. !             EMIT2('\345');
  159.               return OK;
  160.   
  161. !         case 'c': case '\347':
  162. !             EMIT2('c');        EMIT2('\347');
  163.               return OK;
  164.   
  165. !         case 'e': case '\350': case '\351': case '\352': case '\353':
  166. !             EMIT2('e');        EMIT2('\350');  EMIT2('\351');
  167. !             EMIT2('\352');  EMIT2('\353');
  168.               return OK;
  169.   
  170. !         case 'i': case '\354': case '\355': case '\356': case '\357':
  171. !             EMIT2('i');        EMIT2('\354');  EMIT2('\355');
  172. !             EMIT2('\356');  EMIT2('\357');
  173.               return OK;
  174.   
  175. !         case 'n': case '\361':
  176. !             EMIT2('n');        EMIT2('\361');
  177.               return OK;
  178.   
  179. !         case 'o': case '\362': case '\363': case '\364': case '\365':
  180. !         case '\366':
  181. !             EMIT2('o');        EMIT2('\362');  EMIT2('\363');
  182. !             EMIT2('\364');  EMIT2('\365');  EMIT2('\366');
  183.               return OK;
  184.   
  185. !         case 'u': case '\371': case '\372': case '\373': case '\374':
  186. !             EMIT2('u');        EMIT2('\371');  EMIT2('\372');
  187. !             EMIT2('\373');  EMIT2('\374');
  188.               return OK;
  189.   
  190. !         case 'y': case '\375': case '\377':
  191. !             EMIT2('y');        EMIT2('\375');  EMIT2('\377');
  192.               return OK;
  193.   
  194.           default:
  195. --- 684,767 ----
  196.       {
  197.       switch (c)
  198.       {
  199. !         case 'A': case 0300: case 0301: case 0302:
  200. !         case 0303: case 0304: case 0305:
  201. !             EMIT2('A');        EMIT2(0300);  EMIT2(0301);
  202. !             EMIT2(0302);  EMIT2(0303);  EMIT2(0304);
  203. !             EMIT2(0305);
  204.               return OK;
  205.   
  206. !         case 'C': case 0307:
  207. !             EMIT2('C');        EMIT2(0307);
  208.               return OK;
  209.   
  210. !         case 'E': case 0310: case 0311: case 0312: case 0313:
  211. !             EMIT2('E');        EMIT2(0310);  EMIT2(0311);
  212. !             EMIT2(0312);  EMIT2(0313);
  213.               return OK;
  214.   
  215. !         case 'I': case 0314: case 0315: case 0316: case 0317:
  216. !             EMIT2('I');        EMIT2(0314);  EMIT2(0315);
  217. !             EMIT2(0316);  EMIT2(0317);
  218.               return OK;
  219.   
  220. !         case 'N': case 0321:
  221. !             EMIT2('N');        EMIT2(0321);
  222.               return OK;
  223.   
  224. !         case 'O': case 0322: case 0323: case 0324: case 0325:
  225. !         case 0326:
  226. !             EMIT2('O');        EMIT2(0322);  EMIT2(0323);
  227. !             EMIT2(0324);  EMIT2(0325);  EMIT2(0326);
  228.               return OK;
  229.   
  230. !         case 'U': case 0331: case 0332: case 0333: case 0334:
  231. !             EMIT2('U');        EMIT2(0331);  EMIT2(0332);
  232. !             EMIT2(0333);  EMIT2(0334);
  233.               return OK;
  234.   
  235. !         case 'Y': case 0335:
  236. !             EMIT2('Y');        EMIT2(0335);
  237.               return OK;
  238.   
  239. !         case 'a': case 0340: case 0341: case 0342:
  240. !         case 0343: case 0344: case 0345:
  241. !             EMIT2('a');        EMIT2(0340);  EMIT2(0341);
  242. !             EMIT2(0342);  EMIT2(0343);  EMIT2(0344);
  243. !             EMIT2(0345);
  244.               return OK;
  245.   
  246. !         case 'c': case 0347:
  247. !             EMIT2('c');        EMIT2(0347);
  248.               return OK;
  249.   
  250. !         case 'e': case 0350: case 0351: case 0352: case 0353:
  251. !             EMIT2('e');        EMIT2(0350);  EMIT2(0351);
  252. !             EMIT2(0352);  EMIT2(0353);
  253.               return OK;
  254.   
  255. !         case 'i': case 0354: case 0355: case 0356: case 0357:
  256. !             EMIT2('i');        EMIT2(0354);  EMIT2(0355);
  257. !             EMIT2(0356);  EMIT2(0357);
  258.               return OK;
  259.   
  260. !         case 'n': case 0361:
  261. !             EMIT2('n');        EMIT2(0361);
  262.               return OK;
  263.   
  264. !         case 'o': case 0362: case 0363: case 0364: case 0365:
  265. !         case 0366:
  266. !             EMIT2('o');        EMIT2(0362);  EMIT2(0363);
  267. !             EMIT2(0364);  EMIT2(0365);  EMIT2(0366);
  268.               return OK;
  269.   
  270. !         case 'u': case 0371: case 0372: case 0373: case 0374:
  271. !             EMIT2('u');        EMIT2(0371);  EMIT2(0372);
  272. !             EMIT2(0373);  EMIT2(0374);
  273.               return OK;
  274.   
  275. !         case 'y': case 0375: case 0377:
  276. !             EMIT2('y');        EMIT2(0375);  EMIT2(0377);
  277.               return OK;
  278.   
  279.           default:
  280. ***************
  281. *** 811,824 ****
  282.       char_u    *old_regparse = regparse;
  283.   #endif
  284.       int        extra = 0;
  285. -     int        first;
  286.       int        emit_range;
  287.       int        negated;
  288.       int        result;
  289.       int        startc = -1;
  290.       int        endc = -1;
  291.       int        oldstartc = -1;
  292. -     int        glue;        /* ID that will "glue" nodes together */
  293.   
  294.       c = getchr();
  295.       switch (c)
  296. --- 808,819 ----
  297. ***************
  298. *** 927,934 ****
  299.   
  300.       case Magic('n'):
  301.           if (reg_string)
  302. !         /* In a string "\n" matches a newline character. */
  303. !         EMIT(NL);
  304.           else
  305.           {
  306.           /* In buffer text "\n" matches the end of a line. */
  307. --- 922,929 ----
  308.   
  309.       case Magic('n'):
  310.           if (reg_string)
  311. !         /* In a string "\n" matches a newline character. */
  312. !         EMIT(NL);
  313.           else
  314.           {
  315.           /* In buffer text "\n" matches the end of a line. */
  316. ***************
  317. *** 1160,1191 ****
  318.       case Magic('['):
  319.   collection:
  320.           /*
  321. !          * Glue is emitted between several atoms from the [].
  322. !          * It is either NFA_OR, or NFA_CONCAT.
  323. !          *
  324. !          * [abc] expands to 'a b NFA_OR c NFA_OR' (in postfix notation)
  325. !          * [^abc] expands to 'a NFA_NOT b NFA_NOT NFA_CONCAT c NFA_NOT
  326. !          *        NFA_CONCAT NFA_END_NEG_RANGE NFA_CONCAT' (in postfix
  327. !          *        notation)
  328. !          *
  329.            */
  330.   
  331. - /* Emit negation atoms, if needed.
  332. -  * The CONCAT below merges the NOT with the previous node. */
  333. - #define TRY_NEG()            \
  334. -         if (negated == TRUE)    \
  335. -         {                \
  336. -         EMIT(NFA_NOT);        \
  337. -         }
  338. - /* Emit glue between important nodes : CONCAT or OR. */
  339. - #define EMIT_GLUE()            \
  340. -         if (first == FALSE)        \
  341. -         EMIT(glue);        \
  342. -         else            \
  343. -         first = FALSE;
  344.           p = regparse;
  345.           endp = skip_anyof(p);
  346.           if (*endp == ']')
  347. --- 1155,1169 ----
  348.       case Magic('['):
  349.   collection:
  350.           /*
  351. !          * [abc]  uses NFA_START_COLL - NFA_END_COLL
  352. !          * [^abc] uses NFA_START_NEG_COLL - NFA_END_NEG_COLL
  353. !          * Each character is produced as a regular state, using
  354. !          * NFA_CONCAT to bind them together.
  355. !          * Besides normal characters there can be:
  356. !          * - character classes  NFA_CLASS_*
  357. !          * - ranges, two characters followed by NFA_RANGE.
  358.            */
  359.   
  360.           p = regparse;
  361.           endp = skip_anyof(p);
  362.           if (*endp == ']')
  363. ***************
  364. *** 1216,1236 ****
  365.            * version that turns [abc] into 'a' OR 'b' OR 'c'
  366.            */
  367.           startc = endc = oldstartc = -1;
  368. -         first = TRUE;        /* Emitting first atom in this sequence? */
  369.           negated = FALSE;
  370. -         glue = NFA_OR;
  371.           if (*regparse == '^')            /* negated range */
  372.           {
  373.               negated = TRUE;
  374. -             glue = NFA_CONCAT;
  375.               mb_ptr_adv(regparse);
  376.           }
  377.           if (*regparse == '-')
  378.           {
  379.               startc = '-';
  380.               EMIT(startc);
  381. !             TRY_NEG();
  382. !             EMIT_GLUE();
  383.               mb_ptr_adv(regparse);
  384.           }
  385.           /* Emit the OR branches for each character in the [] */
  386. --- 1194,1213 ----
  387.            * version that turns [abc] into 'a' OR 'b' OR 'c'
  388.            */
  389.           startc = endc = oldstartc = -1;
  390.           negated = FALSE;
  391.           if (*regparse == '^')            /* negated range */
  392.           {
  393.               negated = TRUE;
  394.               mb_ptr_adv(regparse);
  395. +             EMIT(NFA_START_NEG_COLL);
  396.           }
  397. +         else
  398. +             EMIT(NFA_START_COLL);
  399.           if (*regparse == '-')
  400.           {
  401.               startc = '-';
  402.               EMIT(startc);
  403. !             EMIT(NFA_CONCAT);
  404.               mb_ptr_adv(regparse);
  405.           }
  406.           /* Emit the OR branches for each character in the [] */
  407. ***************
  408. *** 1306,1325 ****
  409.                       EMIT(NFA_CLASS_ESCAPE);
  410.                       break;
  411.                   }
  412. !                 TRY_NEG();
  413. !                 EMIT_GLUE();
  414.                   continue;
  415.               }
  416.               /* Try equivalence class [=a=] and the like */
  417.               if (equiclass != 0)
  418.               {
  419. !                 result = nfa_emit_equi_class(equiclass, negated);
  420.                   if (result == FAIL)
  421.                   {
  422.                   /* should never happen */
  423.                   EMSG_RET_FAIL(_("E868: Error building NFA with equivalence class!"));
  424.                   }
  425. -                 EMIT_GLUE();
  426.                   continue;
  427.               }
  428.               /* Try collating class like [. .]  */
  429. --- 1283,1300 ----
  430.                       EMIT(NFA_CLASS_ESCAPE);
  431.                       break;
  432.                   }
  433. !                 EMIT(NFA_CONCAT);
  434.                   continue;
  435.               }
  436.               /* Try equivalence class [=a=] and the like */
  437.               if (equiclass != 0)
  438.               {
  439. !                 result = nfa_emit_equi_class(equiclass);
  440.                   if (result == FAIL)
  441.                   {
  442.                   /* should never happen */
  443.                   EMSG_RET_FAIL(_("E868: Error building NFA with equivalence class!"));
  444.                   }
  445.                   continue;
  446.               }
  447.               /* Try collating class like [. .]  */
  448. ***************
  449. *** 1391,1409 ****
  450.               startc = oldstartc;
  451.               if (startc > endc)
  452.                   EMSG_RET_FAIL(_(e_invrange));
  453.   #ifdef FEAT_MBYTE
  454. !             if (has_mbyte && ((*mb_char2len)(startc) > 1
  455.                       || (*mb_char2len)(endc) > 1))
  456.               {
  457. !                 if (endc > startc + 256)
  458. !                 EMSG_RET_FAIL(_(e_invrange));
  459. !                 /* Emit the range. "startc" was already emitted, so
  460. !                  * skip it. */
  461.                   for (c = startc + 1; c <= endc; c++)
  462.                   {
  463.                   EMIT(c);
  464. !                 TRY_NEG();
  465. !                 EMIT_GLUE();
  466.                   }
  467.               }
  468.               else
  469. --- 1366,1397 ----
  470.               startc = oldstartc;
  471.               if (startc > endc)
  472.                   EMSG_RET_FAIL(_(e_invrange));
  473. +             if (endc > startc + 2)
  474. +             {
  475. +                 /* Emit a range instead of the sequence of
  476. +                  * individual characters. */
  477. +                 if (startc == 0)
  478. +                 /* \x00 is translated to \x0a, start at \x01. */
  479. +                 EMIT(1);
  480. +                 else
  481. +                 --post_ptr; /* remove NFA_CONCAT */
  482. +                 EMIT(endc);
  483. +                 EMIT(NFA_RANGE);
  484. +                 EMIT(NFA_CONCAT);
  485. +             }
  486. +             else
  487.   #ifdef FEAT_MBYTE
  488. !                  if (has_mbyte && ((*mb_char2len)(startc) > 1
  489.                       || (*mb_char2len)(endc) > 1))
  490.               {
  491. !                 /* Emit the characters in the range.
  492. !                  * "startc" was already emitted, so skip it.
  493. !                  * */
  494.                   for (c = startc + 1; c <= endc; c++)
  495.                   {
  496.                   EMIT(c);
  497. !                 EMIT(NFA_CONCAT);
  498.                   }
  499.               }
  500.               else
  501. ***************
  502. *** 1425,1432 ****
  503.   #endif
  504.                   {
  505.                       EMIT(c);
  506. !                     TRY_NEG();
  507. !                     EMIT_GLUE();
  508.                   }
  509.               }
  510.               emit_range = FALSE;
  511. --- 1413,1419 ----
  512.   #endif
  513.                   {
  514.                       EMIT(c);
  515. !                     EMIT(NFA_CONCAT);
  516.                   }
  517.               }
  518.               emit_range = FALSE;
  519. ***************
  520. *** 1434,1456 ****
  521.               }
  522.               else
  523.               {
  524. !             /*
  525. !              * This char (startc) is not part of a range. Just
  526.                * emit it.
  527. -              *
  528.                * Normally, simply emit startc. But if we get char
  529.                * code=0 from a collating char, then replace it with
  530.                * 0x0a.
  531. -              *
  532.                * This is needed to completely mimic the behaviour of
  533. !              * the backtracking engine.
  534. !              */
  535. !             if (got_coll_char == TRUE && startc == 0)
  536. !                 EMIT(0x0a);
  537.               else
  538. !                 EMIT(startc);
  539. !             TRY_NEG();
  540. !             EMIT_GLUE();
  541.               }
  542.   
  543.               mb_ptr_adv(regparse);
  544. --- 1421,1449 ----
  545.               }
  546.               else
  547.               {
  548. !             /* This char (startc) is not part of a range. Just
  549.                * emit it.
  550.                * Normally, simply emit startc. But if we get char
  551.                * code=0 from a collating char, then replace it with
  552.                * 0x0a.
  553.                * This is needed to completely mimic the behaviour of
  554. !              * the backtracking engine. */
  555. !             if (startc == NFA_NEWL)
  556. !             {
  557. !                 /* Line break can't be matched as part of the
  558. !                  * collection, add an OR below. But not for negated
  559. !                  * range. */
  560. !                 if (!negated)
  561. !                 extra = ADD_NL;
  562. !             }
  563.               else
  564. !             {
  565. !                 if (got_coll_char == TRUE && startc == 0)
  566. !                 EMIT(0x0a);
  567. !                 else
  568. !                 EMIT(startc);
  569. !                 EMIT(NFA_CONCAT);
  570. !             }
  571.               }
  572.   
  573.               mb_ptr_adv(regparse);
  574. ***************
  575. *** 1460,1479 ****
  576.           if (*regparse == '-')        /* if last, '-' is just a char */
  577.           {
  578.               EMIT('-');
  579. !             TRY_NEG();
  580. !             EMIT_GLUE();
  581.           }
  582.           mb_ptr_adv(regparse);
  583.   
  584.           /* skip the trailing ] */
  585.           regparse = endp;
  586.           mb_ptr_adv(regparse);
  587.           if (negated == TRUE)
  588. !         {
  589. !             /* Mark end of negated char range */
  590. !             EMIT(NFA_END_NEG_RANGE);
  591. !             EMIT(NFA_CONCAT);
  592. !         }
  593.   
  594.           /* \_[] also matches \n but it's not negated */
  595.           if (extra == ADD_NL)
  596. --- 1453,1471 ----
  597.           if (*regparse == '-')        /* if last, '-' is just a char */
  598.           {
  599.               EMIT('-');
  600. !             EMIT(NFA_CONCAT);
  601.           }
  602.           mb_ptr_adv(regparse);
  603.   
  604.           /* skip the trailing ] */
  605.           regparse = endp;
  606.           mb_ptr_adv(regparse);
  607. +         /* Mark end of the collection. */
  608.           if (negated == TRUE)
  609. !             EMIT(NFA_END_NEG_COLL);
  610. !         else
  611. !             EMIT(NFA_END_COLL);
  612.   
  613.           /* \_[] also matches \n but it's not negated */
  614.           if (extra == ADD_NL)
  615. ***************
  616. *** 1532,1540 ****
  617.           }
  618.       }
  619.   
  620. - #undef TRY_NEG
  621. - #undef EMIT_GLUE
  622.       return OK;
  623.   }
  624.   
  625. --- 1524,1529 ----
  626. ***************
  627. *** 2091,2100 ****
  628.       case NFA_STAR_NONGREEDY: STRCPY(code, "NFA_STAR_NONGREEDY "); break;
  629.       case NFA_QUEST:        STRCPY(code, "NFA_QUEST"); break;
  630.       case NFA_QUEST_NONGREEDY: STRCPY(code, "NFA_QUEST_NON_GREEDY"); break;
  631. -     case NFA_NOT:        STRCPY(code, "NFA_NOT "); break;
  632.       case NFA_SKIP_CHAR:    STRCPY(code, "NFA_SKIP_CHAR"); break;
  633.       case NFA_OR:        STRCPY(code, "NFA_OR"); break;
  634. !     case NFA_END_NEG_RANGE:    STRCPY(code, "NFA_END_NEG_RANGE"); break;
  635.       case NFA_CLASS_ALNUM:    STRCPY(code, "NFA_CLASS_ALNUM"); break;
  636.       case NFA_CLASS_ALPHA:    STRCPY(code, "NFA_CLASS_ALPHA"); break;
  637.       case NFA_CLASS_BLANK:    STRCPY(code, "NFA_CLASS_BLANK"); break;
  638. --- 2080,2096 ----
  639.       case NFA_STAR_NONGREEDY: STRCPY(code, "NFA_STAR_NONGREEDY "); break;
  640.       case NFA_QUEST:        STRCPY(code, "NFA_QUEST"); break;
  641.       case NFA_QUEST_NONGREEDY: STRCPY(code, "NFA_QUEST_NON_GREEDY"); break;
  642.       case NFA_SKIP_CHAR:    STRCPY(code, "NFA_SKIP_CHAR"); break;
  643.       case NFA_OR:        STRCPY(code, "NFA_OR"); break;
  644. !     case NFA_START_COLL:    STRCPY(code, "NFA_START_COLL"); break;
  645. !     case NFA_END_COLL:    STRCPY(code, "NFA_END_COLL"); break;
  646. !     case NFA_START_NEG_COLL: STRCPY(code, "NFA_START_NEG_COLL"); break;
  647. !     case NFA_END_NEG_COLL:    STRCPY(code, "NFA_END_NEG_COLL"); break;
  648. !     case NFA_RANGE:        STRCPY(code, "NFA_RANGE"); break;
  649. !     case NFA_RANGE_MIN:    STRCPY(code, "NFA_RANGE_MIN"); break;
  650. !     case NFA_RANGE_MAX:    STRCPY(code, "NFA_RANGE_MAX"); break;
  651.       case NFA_CLASS_ALNUM:    STRCPY(code, "NFA_CLASS_ALNUM"); break;
  652.       case NFA_CLASS_ALPHA:    STRCPY(code, "NFA_CLASS_ALPHA"); break;
  653.       case NFA_CLASS_BLANK:    STRCPY(code, "NFA_CLASS_BLANK"); break;
  654. ***************
  655. *** 2231,2238 ****
  656.       fprintf(debugf, " %s", p);
  657.   
  658.       nfa_set_code(state->c);
  659. !     fprintf(debugf, "%s%s (%d) (id=%d)\n",
  660. !          state->negated ? "NOT " : "", code, state->c, abs(state->id));
  661.       if (state->id < 0)
  662.       return;
  663.   
  664. --- 2227,2238 ----
  665.       fprintf(debugf, " %s", p);
  666.   
  667.       nfa_set_code(state->c);
  668. !     fprintf(debugf, "%s%s (%d) (id=%d) val=%d\n",
  669. !          state->negated ? "NOT " : "",
  670. !          code,
  671. !          state->c,
  672. !          abs(state->id),
  673. !          state->val);
  674.       if (state->id < 0)
  675.       return;
  676.   
  677. ***************
  678. *** 2325,2330 ****
  679. --- 2325,2331 ----
  680.       s->c    = c;
  681.       s->out  = out;
  682.       s->out1 = out1;
  683. +     s->val  = 0;
  684.   
  685.       s->id   = istate;
  686.       s->lastlist[0] = 0;
  687. ***************
  688. *** 2565,2577 ****
  689.       switch (*p)
  690.       {
  691.       case NFA_CONCAT:
  692. !         /* Catenation.
  693. !          * Pay attention: this operator does not exist
  694. !          * in the r.e. itself (it is implicit, really).
  695. !          * It is added when r.e. is translated to postfix
  696. !          * form in re2post().
  697. !          *
  698. !          * No new state added here. */
  699.           if (nfa_calc_size == TRUE)
  700.           {
  701.           /* nstate += 0; */
  702. --- 2566,2575 ----
  703.       switch (*p)
  704.       {
  705.       case NFA_CONCAT:
  706. !         /* Concatenation.
  707. !          * Pay attention: this operator does not exist in the r.e. itself
  708. !          * (it is implicit, really).  It is added when r.e. is translated
  709. !          * to postfix form in re2post(). */
  710.           if (nfa_calc_size == TRUE)
  711.           {
  712.           /* nstate += 0; */
  713. ***************
  714. *** 2583,2604 ****
  715.           PUSH(frag(e1.start, e2.out));
  716.           break;
  717.   
  718. -     case NFA_NOT:
  719. -         /* Negation of a character */
  720. -         if (nfa_calc_size == TRUE)
  721. -         {
  722. -         /* nstate += 0; */
  723. -         break;
  724. -         }
  725. -         e1 = POP();
  726. -         e1.start->negated = TRUE;
  727. - #ifdef FEAT_MBYTE
  728. -         if (e1.start->c == NFA_COMPOSING)
  729. -         e1.start->out1->negated = TRUE;
  730. - #endif
  731. -         PUSH(e1);
  732. -         break;
  733.       case NFA_OR:
  734.           /* Alternation */
  735.           if (nfa_calc_size == TRUE)
  736. --- 2581,2586 ----
  737. ***************
  738. *** 2672,2677 ****
  739. --- 2654,2696 ----
  740.           PUSH(frag(s, append(e.out, list1(&s->out))));
  741.           break;
  742.   
  743. +     case NFA_END_COLL:
  744. +     case NFA_END_NEG_COLL:
  745. +         /* On the stack is the sequence starting with NFA_START_COLL or
  746. +          * NFA_START_NEG_COLL and all possible characters. Patch it to
  747. +          * add the output to the start. */
  748. +         if (nfa_calc_size == TRUE)
  749. +         {
  750. +         nstate++;
  751. +         break;
  752. +         }
  753. +         e = POP();
  754. +         s = alloc_state(NFA_END_COLL, NULL, NULL);
  755. +         if (s == NULL)
  756. +         goto theend;
  757. +         patch(e.out, s);
  758. +         e.start->out1 = s;
  759. +         PUSH(frag(e.start, list1(&s->out)));
  760. +         break;
  761. +     case NFA_RANGE:
  762. +         /* Before this are two characters, the low and high end of a
  763. +          * range.  Turn them into two states with MIN and MAX. */
  764. +         if (nfa_calc_size == TRUE)
  765. +         {
  766. +         /* nstate += 0; */
  767. +         break;
  768. +         }
  769. +         e2 = POP();
  770. +         e1 = POP();
  771. +         e2.start->val = e2.start->c;
  772. +         e2.start->c = NFA_RANGE_MAX;
  773. +         e1.start->val = e1.start->c;
  774. +         e1.start->c = NFA_RANGE_MIN;
  775. +         patch(e1.out, e2.start);
  776. +         PUSH(frag(e1.start, e2.out));
  777. +         break;
  778.       case NFA_SKIP_CHAR:
  779.           /* Symbol of 0-length, Used in a repetition
  780.            * with max/min count of 0 */
  781. ***************
  782. *** 2990,2995 ****
  783. --- 3009,3016 ----
  784.       matchstate = &state_ptr[istate++]; /* the match state */
  785.       matchstate->c = NFA_MATCH;
  786.       matchstate->out = matchstate->out1 = NULL;
  787. +     matchstate->negated = FALSE;
  788. +     matchstate->id = 0;
  789.   
  790.       patch(e.out, matchstate);
  791.       ret = e.start;
  792. ***************
  793. *** 3308,3314 ****
  794.       switch (state->c)
  795.       {
  796.       case NFA_SPLIT:
  797. -     case NFA_NOT:
  798.       case NFA_NOPEN:
  799.       case NFA_SKIP_CHAR:
  800.       case NFA_NCLOSE:
  801. --- 3329,3334 ----
  802. ***************
  803. *** 3782,3788 ****
  804.   
  805.       default:
  806.           /* should not be here :P */
  807. !         EMSG_RET_FAIL(_("E877: (NFA regexp) Invalid character class "));
  808.       }
  809.       return FAIL;
  810.   }
  811. --- 3802,3809 ----
  812.   
  813.       default:
  814.           /* should not be here :P */
  815. !         EMSGN("E877: (NFA regexp) Invalid character class: %ld", class);
  816. !         return FAIL;
  817.       }
  818.       return FAIL;
  819.   }
  820. ***************
  821. *** 4320,4327 ****
  822.       addstate(thislist, start, m, 0);
  823.   
  824.       /* There are two cases when the NFA advances: 1. input char matches the
  825. !      * NFA node and 2. input char does not match the NFA node, but the next
  826. !      * node is NFA_NOT. The following macro calls addstate() according to
  827.        * these rules. It is used A LOT, so use the "listtbl" table for speed */
  828.       listtbl[0][0] = NULL;
  829.       listtbl[0][1] = neglist;
  830. --- 4341,4348 ----
  831.       addstate(thislist, start, m, 0);
  832.   
  833.       /* There are two cases when the NFA advances: 1. input char matches the
  834. !      * NFA node and 2. input char does not match the NFA node and the state
  835. !      * has the negated flag. The following macro calls addstate() according to
  836.        * these rules. It is used A LOT, so use the "listtbl" table for speed */
  837.       listtbl[0][0] = NULL;
  838.       listtbl[0][1] = neglist;
  839. ***************
  840. *** 4845,4860 ****
  841.           ADD_POS_NEG_STATE(t->state);
  842.           break;
  843.   
  844. !         case NFA_END_NEG_RANGE:
  845. !         /* This follows a series of negated nodes, like:
  846. !          * NOT CHAR(x), NOT CHAR(y), etc. */
  847. !         if (curc > 0)
  848.           {
  849.               ll = nextlist;
  850. !             add_state = t->state->out;
  851.               add_off = clen;
  852.           }
  853.           break;
  854.   
  855.           case NFA_ANY:
  856.           /* Any char except '\0', (end of input) does not match. */
  857. --- 4866,4944 ----
  858.           ADD_POS_NEG_STATE(t->state);
  859.           break;
  860.   
  861. !         case NFA_START_COLL:
  862. !         case NFA_START_NEG_COLL:
  863. !           {
  864. !         /* What follows is a list of characters, until NFA_END_COLL.
  865. !          * One of them must match or none of them must match. */
  866. !         nfa_state_T    *state;
  867. !         int        result_if_matched;
  868. !         int        c1, c2;
  869. !         /* Never match EOL. If it's part of the collection it is added
  870. !          * as a separate state with an OR. */
  871. !         if (curc == NUL)
  872. !             break;
  873. !         state = t->state->out;
  874. !         result_if_matched = (t->state->c == NFA_START_COLL);
  875. !         for (;;)
  876.           {
  877. +             if (state->c == NFA_END_COLL)
  878. +             {
  879. +             result = !result_if_matched;
  880. +             break;
  881. +             }
  882. +             if (state->c == NFA_RANGE_MIN)
  883. +             {
  884. +             c1 = state->val;
  885. +             state = state->out; /* advance to NFA_RANGE_MAX */
  886. +             c2 = state->val;
  887. + #ifdef ENABLE_LOG
  888. +             fprintf(log_fd, "NFA_RANGE_MIN curc=%d c1=%d c2=%d\n",
  889. +                 curc, c1, c2);
  890. + #endif
  891. +             if (curc >= c1 && curc <= c2)
  892. +             {
  893. +                 result = result_if_matched;
  894. +                 break;
  895. +             }
  896. +             if (ireg_ic)
  897. +             {
  898. +                 int curc_low = MB_TOLOWER(curc);
  899. +                 int done = FALSE;
  900. +                 for ( ; c1 <= c2; ++c1)
  901. +                 if (MB_TOLOWER(c1) == curc_low)
  902. +                 {
  903. +                     result = result_if_matched;
  904. +                     done = TRUE;
  905. +                     break;
  906. +                 }
  907. +                 if (done)
  908. +                 break;
  909. +             }
  910. +             }
  911. +             else if (state->c < 0 ? check_char_class(state->c, curc)
  912. +                     : (curc == state->c
  913. +                    || (ireg_ic && MB_TOLOWER(curc)
  914. +                             == MB_TOLOWER(state->c))))
  915. +             {
  916. +             result = result_if_matched;
  917. +             break;
  918. +             }
  919. +             state = state->out;
  920. +         }
  921. +         if (result)
  922. +         {
  923. +             /* next state is in out of the NFA_END_COLL, out1 of
  924. +              * START points to the END state */
  925.               ll = nextlist;
  926. !             add_state = t->state->out1->out;
  927.               add_off = clen;
  928.           }
  929.           break;
  930. +           }
  931.   
  932.           case NFA_ANY:
  933.           /* Any char except '\0', (end of input) does not match. */
  934. *** ../vim-7.3.1136/src/version.c    2013-06-06 21:31:02.000000000 +0200
  935. --- src/version.c    2013-06-07 13:21:57.000000000 +0200
  936. ***************
  937. *** 730,731 ****
  938. --- 730,733 ----
  939.   {   /* Add new patch number below this line */
  940. + /**/
  941. +     1137,
  942.   /**/
  943.  
  944. -- 
  945. From "know your smileys":
  946.  :.-(    Crying
  947.  
  948.  /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
  949. ///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
  950. \\\  an exciting new programming language -- http://www.Zimbu.org        ///
  951.  \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
  952.