]> granicus.if.org Git - vim/commitdiff
updated for version 7.3.1039 v7.3.1039
authorBram Moolenaar <Bram@vim.org>
Wed, 29 May 2013 19:14:42 +0000 (21:14 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 29 May 2013 19:14:42 +0000 (21:14 +0200)
Problem:    New regexp engine does not support \%23c, \%<23c and the like.
Solution:   Implement them. (partly by Yasuhiro Matsumoto)

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

index f8ff0962aa4f101c1ca42f470f75b0fa52ea5116..69075b5f58bcd1cca441fefb65241a01ef212f90 100644 (file)
@@ -72,6 +72,7 @@ struct nfa_state
     int                        id;
     int                        lastlist;
     int                        negated;
+    int                        val;
 };
 
 /*
index 88c813d2e2f0bf82028ab15fbb44824b3417a19e..bb8c982fe77e6a7137631ff896aaba3044d4eeff 100644 (file)
@@ -117,6 +117,18 @@ enum
     NFA_NLOWER,                /*      Match non-lowercase char */
     NFA_UPPER,         /*      Match uppercase char */
     NFA_NUPPER,                /*      Match non-uppercase char */
+
+    NFA_CURSOR,                /*      Match cursor pos */
+    NFA_LNUM,          /*      Match line number */
+    NFA_LNUM_GT,       /*      Match > line number */
+    NFA_LNUM_LT,       /*      Match < line number */
+    NFA_COL,           /*      Match cursor column */
+    NFA_COL_GT,                /*      Match > cursor column */
+    NFA_COL_LT,                /*      Match < cursor column */
+    NFA_VCOL,          /*      Match cursor virtual column */
+    NFA_VCOL_GT,       /*      Match > cursor virtual column */
+    NFA_VCOL_LT,       /*      Match < cursor virtual column */
+
     NFA_FIRST_NL = NFA_ANY + ADD_NL,
     NFA_LAST_NL = NFA_NUPPER + ADD_NL,
 
@@ -205,10 +217,11 @@ static nfa_state_T *new_state __ARGS((int c, nfa_state_T *out, nfa_state_T *out1
 static nfa_state_T *post2nfa __ARGS((int *postfix, int *end, int nfa_calc_size));
 static int check_char_class __ARGS((int class, int c));
 static void st_error __ARGS((int *postfix, int *end, int *p));
+static void nfa_set_neg_listids __ARGS((nfa_state_T *start));
+static void nfa_set_null_listids __ARGS((nfa_state_T *start));
 static void nfa_save_listids __ARGS((nfa_state_T *start, int *list));
 static void nfa_restore_listids __ARGS((nfa_state_T *start, int *list));
-static void nfa_set_null_listids __ARGS((nfa_state_T *start));
-static void nfa_set_neg_listids __ARGS((nfa_state_T *start));
+static int nfa_re_num_cmp __ARGS((long_u val, int op, long_u pos));
 static long nfa_regtry __ARGS((nfa_state_T *start, colnr_T col));
 static long nfa_regexec_both __ARGS((char_u *line, colnr_T col));
 static regprog_T *nfa_regcomp __ARGS((char_u *expr, int re_flags));
@@ -831,8 +844,7 @@ nfa_regatom()
                    break;
 
                case '#':
-                   /* TODO: not supported yet */
-                   return FAIL;
+                   EMIT(NFA_CURSOR);
                    break;
 
                case 'V':
@@ -844,23 +856,36 @@ nfa_regatom()
                    /* TODO: \%[abc] not supported yet */
                    return FAIL;
 
-               case '0':
-               case '1':
-               case '2':
-               case '3':
-               case '4':
-               case '5':
-               case '6':
-               case '7':
-               case '8':
-               case '9':
-               case '<':
-               case '>':
-               case '\'':
-                   /* TODO: not supported yet */
-                   return FAIL;
-
                default:
+                   {
+                       long_u  n = 0;
+                       int     cmp = c;
+
+                       if (c == '<' || c == '>')
+                           c = getchr();
+                       while (VIM_ISDIGIT(c))
+                       {
+                           n = n * 10 + (c - '0');
+                           c = getchr();
+                       }
+                       if (c == 'l' || c == 'c' || c == 'v')
+                       {
+                           EMIT(n);
+                           if (c == 'l')
+                               EMIT(cmp == '<' ? NFA_LNUM_LT :
+                                       cmp == '>' ? NFA_LNUM_GT : NFA_LNUM);
+                           else if (c == 'c')
+                               EMIT(cmp == '<' ? NFA_COL_LT :
+                                       cmp == '>' ? NFA_COL_GT : NFA_COL);
+                           else
+                               EMIT(cmp == '<' ? NFA_VCOL_LT :
+                                       cmp == '>' ? NFA_VCOL_GT : NFA_VCOL);
+                           break;
+                       }
+                       else if (c == '\'')
+                           /* TODO: \%'m not supported yet */
+                           return FAIL;
+                   }
                    syntax_error = TRUE;
                    EMSGN(_("E867: (NFA) Unknown operator '\\%%%c'"),
                                                                 no_Magic(c));
@@ -1679,6 +1704,8 @@ nfa_set_code(c)
 
        case NFA_PREV_ATOM_NO_WIDTH:
                            STRCPY(code, "NFA_PREV_ATOM_NO_WIDTH"); break;
+       case NFA_PREV_ATOM_NO_WIDTH_NEG:
+                           STRCPY(code, "NFA_PREV_ATOM_NO_WIDTH_NEG"); break;
        case NFA_NOPEN:             STRCPY(code, "NFA_MOPEN_INVISIBLE"); break;
        case NFA_NCLOSE:            STRCPY(code, "NFA_MCLOSE_INVISIBLE"); break;
        case NFA_START_INVISIBLE:   STRCPY(code, "NFA_START_INVISIBLE"); break;
@@ -2444,6 +2471,28 @@ post2nfa(postfix, end, nfa_calc_size)
            PUSH(frag(s, list1(&s1->out)));
            break;
 
+       case NFA_LNUM:
+       case NFA_LNUM_GT:
+       case NFA_LNUM_LT:
+       case NFA_VCOL:
+       case NFA_VCOL_GT:
+       case NFA_VCOL_LT:
+       case NFA_COL:
+       case NFA_COL_GT:
+       case NFA_COL_LT:
+           if (nfa_calc_size == TRUE)
+           {
+               nstate += 1;
+               break;
+           }
+           e1 = POP();
+           s = new_state(*p, NULL, NULL);
+           if (s == NULL)
+               goto theend;
+           s->val = e1.start->c;
+           PUSH(frag(s, list1(&s->out)));
+           break;
+
        case NFA_ZSTART:
        case NFA_ZEND:
        default:
@@ -3076,6 +3125,17 @@ nfa_restore_listids(start, list)
     }
 }
 
+    static int
+nfa_re_num_cmp(val, op, pos)
+    long_u     val;
+    int                op;
+    long_u     pos;
+{
+    if (op == 1) return pos > val;
+    if (op == 2) return pos < val;
+    return val == pos;
+}
+
 static int nfa_regmatch __ARGS((nfa_state_T *start, regsub_T *submatch, regsub_T *m));
 
 /*
@@ -3791,6 +3851,45 @@ nfa_regmatch(start, submatch, m)
                /* TODO: should not happen? */
                break;
 
+           case NFA_LNUM:
+           case NFA_LNUM_GT:
+           case NFA_LNUM_LT:
+               result = (REG_MULTI &&
+                       nfa_re_num_cmp(t->state->val, t->state->c - NFA_LNUM,
+                           (long_u)(reglnum + reg_firstlnum)));
+               if (result)
+                   addstate_here(thislist, t->state->out, &t->sub, &listidx);
+               break;
+
+           case NFA_COL:
+           case NFA_COL_GT:
+           case NFA_COL_LT:
+               result = nfa_re_num_cmp(t->state->val, t->state->c - NFA_COL,
+                       (long_u)(reginput - regline) + 1);
+               if (result)
+                   addstate_here(thislist, t->state->out, &t->sub, &listidx);
+               break;
+
+           case NFA_VCOL:
+           case NFA_VCOL_GT:
+           case NFA_VCOL_LT:
+               result = nfa_re_num_cmp(t->state->val, t->state->c - NFA_VCOL,
+                   (long_u)win_linetabsize(
+                           reg_win == NULL ? curwin : reg_win,
+                           regline, (colnr_T)(reginput - regline)) + 1);
+               if (result)
+                   addstate_here(thislist, t->state->out, &t->sub, &listidx);
+               break;
+
+           case NFA_CURSOR:
+               result = (reg_win != NULL
+                       && (reglnum + reg_firstlnum == reg_win->w_cursor.lnum)
+                       && ((colnr_T)(reginput - regline)
+                                                  == reg_win->w_cursor.col));
+               if (result)
+                   addstate_here(thislist, t->state->out, &t->sub, &listidx);
+               break;
+
            default:    /* regular character */
              {
                int c = t->state->c;
index 667e194e16a284d7089c1974ea1ed6b46e34281d..192d456725e9d00e516511309d7cfe07330fdd89 100644 (file)
@@ -413,13 +413,40 @@ Go\ep:"
 :.yank
 y$Go\ep:"
 :"
-:"
 :" Check a pattern with a look beind crossing a line boundary
 /^Behind:
 /\(<\_[xy]\+\)\@3<=start
 :.yank
 Go\ep:"
 :"
+:" Check patterns matching cursor position.
+:func! Postest()
+ new
+ call setline(1, ['ffooooo', 'boboooo', 'zoooooo', 'koooooo', 'moooooo', "\t\t\tfoo", 'abababababababfoo', 'bababababababafoo', '********_'])
+ call setpos('.', [0, 1, 0, 0])
+ s/\%>3c.//g
+ call setpos('.', [0, 2, 4, 0])
+ s/\%#.*$//g
+ call setpos('.', [0, 3, 0, 0])
+ s/\%<3c./_/g
+ %s/\%4l\%>5c./_/g
+ %s/\%6l\%>25v./_/g
+ %s/\%>6l\%3c./!/g
+ %s/\%>7l\%12c./?/g
+ %s/\%>7l\%<9l\%>5v\%<8v./#/g
+ 1,$yank
+ quit!
+endfunc
+Go-0-\e:set re=0
+:call Postest()
+:put
+o-1-\e:set re=1
+:call Postest()
+:put
+o-2-\e:set re=2
+:call Postest()
+:put
+:"
 :/\%#=1^Results/,$wq! test.out
 ENDTEST
 
index 3b53d2451e005769e3544a83477f1a1018612e59..74db0bd09b7fa1276c3628ed54d82deff6bf1854 100644 (file)
@@ -740,3 +740,33 @@ OK 1 - \(<<\)\@2<=span.
 ghi
 
 xxxstart3
+-0-
+ffo
+bob
+__ooooo
+koooo__
+moooooo
+                       f__
+ab!babababababfoo
+ba!ab##abab?bafoo
+**!*****_
+-1-
+ffo
+bob
+__ooooo
+koooo__
+moooooo
+                       f__
+ab!babababababfoo
+ba!ab##abab?bafoo
+**!*****_
+-2-
+ffo
+bob
+__ooooo
+koooo__
+moooooo
+                       f__
+ab!babababababfoo
+ba!ab##abab?bafoo
+**!*****_
index d51c249d8ab856629cd1ea15fb779150ee56661c..b9db33d255431f248a245979d883c2531903f9aa 100644 (file)
@@ -728,6 +728,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1039,
 /**/
     1038,
 /**/