]> granicus.if.org Git - vim/commitdiff
updated for version 7.3.1087 v7.3.1087
authorBram Moolenaar <Bram@vim.org>
Sat, 1 Jun 2013 12:42:56 +0000 (14:42 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 1 Jun 2013 12:42:56 +0000 (14:42 +0200)
Problem:    A leading star is not seen as a normal char when \{} follows.
Solution:   Save and restore the parse state properly.

src/regexp.c
src/regexp_nfa.c
src/testdir/test64.in
src/testdir/test64.ok
src/version.c

index f0b93256630c395b2bb0169bec4494c05808f31e..cfeee4c27dfbe02fb022bc01c27a2da35a03a9e9 100644 (file)
@@ -665,10 +665,25 @@ static int        nextchr;        /* used for ungetchr() */
 #define REG_ZPAREN     2       /* \z(\) */
 #define REG_NPAREN     3       /* \%(\) */
 
+typedef struct
+{
+     char_u    *regparse;
+     int       prevchr_len;
+     int       curchr;
+     int       prevchr;
+     int       prevprevchr;
+     int       nextchr;
+     int       at_start;
+     int       prev_at_start;
+     int       regnpar;
+} parse_state_T;
+
 /*
  * Forward declarations for vim_regcomp()'s friends.
  */
 static void    initchr __ARGS((char_u *));
+static void    save_parse_state __ARGS((parse_state_T *ps));
+static void    restore_parse_state __ARGS((parse_state_T *ps));
 static int     getchr __ARGS((void));
 static void    skipchr_keepstart __ARGS((void));
 static int     peekchr __ARGS((void));
@@ -2950,6 +2965,44 @@ initchr(str)
     prev_at_start = FALSE;
 }
 
+/*
+ * Save the current parse state, so that it can be restored and parsing
+ * starts in the same state again.
+ */
+    static void
+save_parse_state(ps)
+    parse_state_T *ps;
+{
+    ps->regparse = regparse;
+    ps->prevchr_len = prevchr_len;
+    ps->curchr = curchr;
+    ps->prevchr = prevchr;
+    ps->prevprevchr = prevprevchr;
+    ps->nextchr = nextchr;
+    ps->at_start = at_start;
+    ps->prev_at_start = prev_at_start;
+    ps->regnpar = regnpar;
+}
+
+/*
+ * Restore a previously saved parse state.
+ */
+    static void
+restore_parse_state(ps)
+    parse_state_T *ps;
+{
+    regparse = ps->regparse;
+    prevchr_len = ps->prevchr_len;
+    curchr = ps->curchr;
+    prevchr = ps->prevchr;
+    prevprevchr = ps->prevprevchr;
+    nextchr = ps->nextchr;
+    at_start = ps->at_start;
+    prev_at_start = ps->prev_at_start;
+    regnpar = ps->regnpar;
+}
+
+
 /*
  * Get the next character without advancing.
  */
index 2d1df6d6365283de2e7fcbd65940784563ae9004..fffe4a0cc297c51875422bdb68ff40693b7f2f44 100644 (file)
@@ -1318,19 +1318,17 @@ nfa_regpiece()
     int                ret;
     long       minval, maxval;
     int                greedy = TRUE;      /* Braces are prefixed with '-' ? */
-    char_u     *old_regparse, *new_regparse;
+    parse_state_T old_state;
+    parse_state_T new_state;
     int                c2;
     int                old_post_pos;
     int                my_post_start;
-    int                old_regnpar;
     int                quest;
 
-    /* Save the current position in the regexp, so that we can use it if
-     * <atom>{m,n} is next. */
-    old_regparse = regparse;
-    /* Save current number of open parenthesis, so we can use it if
-     * <atom>{m,n} is next */
-    old_regnpar = regnpar;
+    /* Save the current parse state, so that we can use it if <atom>{m,n} is
+     * next. */
+    save_parse_state(&old_state);
+
     /* store current pos in the postfix form, for \{m,n} involving 0s */
     my_post_start = (int)(post_ptr - post_start);
 
@@ -1361,8 +1359,7 @@ nfa_regpiece()
             * In order to be consistent with the old engine, we replace
             * <atom>+ with <atom><atom>*
             */
-           regnpar = old_regnpar;
-           regparse = old_regparse;
+           restore_parse_state(&old_state);
            curchr = -1;
            if (nfa_regatom() == FAIL)
                return FAIL;
@@ -1452,17 +1449,14 @@ nfa_regpiece()
 
            /* Ignore previous call to nfa_regatom() */
            post_ptr = post_start + my_post_start;
-           /* Save pos after the repeated atom and the \{} */
-           new_regparse = regparse;
+           /* Save parse state after the repeated atom and the \{} */
+           save_parse_state(&new_state);
 
            quest = (greedy == TRUE? NFA_QUEST : NFA_QUEST_NONGREEDY);
            for (i = 0; i < maxval; i++)
            {
                /* Goto beginning of the repeated atom */
-               regparse = old_regparse;
-               curchr = -1;
-               /* Restore count of parenthesis */
-               regnpar = old_regnpar;
+               restore_parse_state(&old_state);
                old_post_pos = (int)(post_ptr - post_start);
                if (nfa_regatom() == FAIL)
                    return FAIL;
@@ -1486,7 +1480,7 @@ nfa_regpiece()
            }
 
            /* Go to just after the repeated atom and the \{} */
-           regparse = new_regparse;
+           restore_parse_state(&new_state);
            curchr = -1;
 
            break;
index 346e792fae0f8e9fb849cbbdb25b987e55a0e176..962f60ebe37da9cbf9f5af8ebbec1f9fea0fb798 100644 (file)
@@ -188,6 +188,10 @@ STARTTEST
 :call add(tl, [2, 'a\{,0}', 'oidfguih iuhi hiu aaaa', ''])
 :call add(tl, [2, 'a\{,5}', 'abcd', 'a'])
 :call add(tl, [2, 'a\{,5}', 'aaaaaaaaaa', 'aaaaa'])
+:" leading star as normal char when \{} follows
+:call add(tl, [2, '^*\{4,}$', '***'])
+:call add(tl, [2, '^*\{4,}$', '****', '****'])
+:call add(tl, [2, '^*\{4,}$', '*****', '*****'])
 :" same thing as 'a*'
 :call add(tl, [2, 'a\{}', 'bbbcddiuhfcd', ''])
 :call add(tl, [2, 'a\{}', 'aaaaioudfh coisf jda', 'aaaa'])
index fdd55da3855b94823e2334c918a70391caced79c..b014a16cb9506cb1dcdc594b2012f010a3283667 100644 (file)
@@ -407,6 +407,15 @@ OK 2 - a\{,5}
 OK 0 - a\{,5}
 OK 1 - a\{,5}
 OK 2 - a\{,5}
+OK 0 - ^*\{4,}$
+OK 1 - ^*\{4,}$
+OK 2 - ^*\{4,}$
+OK 0 - ^*\{4,}$
+OK 1 - ^*\{4,}$
+OK 2 - ^*\{4,}$
+OK 0 - ^*\{4,}$
+OK 1 - ^*\{4,}$
+OK 2 - ^*\{4,}$
 OK 0 - a\{}
 OK 1 - a\{}
 OK 2 - a\{}
index ec0105e441fcbe5a1d31e875115dd6da8739bd68..641fb6793ade831fea4051925e0358e8d1e3dca1 100644 (file)
@@ -728,6 +728,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1087,
 /**/
     1086,
 /**/