]> granicus.if.org Git - vim/commitdiff
updated for version 7.3.1191 v7.3.1191
authorBram Moolenaar <Bram@vim.org>
Fri, 14 Jun 2013 18:31:28 +0000 (20:31 +0200)
committerBram Moolenaar <Bram@vim.org>
Fri, 14 Jun 2013 18:31:28 +0000 (20:31 +0200)
Problem:    Backreference to previous line doesn't work. (Lech Lorens)
Solution:   Implement looking in another line.

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

index ef8c78db68d02861f96de6dd4a781e4d5a59e3bd..e33e0cfbe1216a33ec44472926fffa01e6b719f8 100644 (file)
@@ -3519,6 +3519,7 @@ static void       save_se_one __ARGS((save_se_T *savep, char_u **pp));
        *(pp) = (savep)->se_u.ptr; }
 
 static int     re_num_cmp __ARGS((long_u val, char_u *scan));
+static int     match_with_backref __ARGS((linenr_T start_lnum, colnr_T start_col, linenr_T end_lnum, colnr_T end_col, int *bytelen));
 static int     regmatch __ARGS((char_u *prog));
 static int     regrepeat __ARGS((char_u *p, long maxcount));
 
@@ -4979,9 +4980,6 @@ regmatch(scan)
          case BACKREF + 9:
            {
                int             len;
-               linenr_T        clnum;
-               colnr_T         ccol;
-               char_u          *p;
 
                no = op - BACKREF;
                cleanup_subexpr();
@@ -5023,67 +5021,12 @@ regmatch(scan)
                        {
                            /* Messy situation: Need to compare between two
                             * lines. */
-                           ccol = reg_startpos[no].col;
-                           clnum = reg_startpos[no].lnum;
-                           for (;;)
-                           {
-                               /* Since getting one line may invalidate
-                                * the other, need to make copy.  Slow! */
-                               if (regline != reg_tofree)
-                               {
-                                   len = (int)STRLEN(regline);
-                                   if (reg_tofree == NULL
-                                                || len >= (int)reg_tofreelen)
-                                   {
-                                       len += 50;      /* get some extra */
-                                       vim_free(reg_tofree);
-                                       reg_tofree = alloc(len);
-                                       if (reg_tofree == NULL)
-                                       {
-                                           status = RA_FAIL; /* outof memory!*/
-                                           break;
-                                       }
-                                       reg_tofreelen = len;
-                                   }
-                                   STRCPY(reg_tofree, regline);
-                                   reginput = reg_tofree
-                                                      + (reginput - regline);
-                                   regline = reg_tofree;
-                               }
-
-                               /* Get the line to compare with. */
-                               p = reg_getline(clnum);
-                               if (clnum == reg_endpos[no].lnum)
-                                   len = reg_endpos[no].col - ccol;
-                               else
-                                   len = (int)STRLEN(p + ccol);
-
-                               if (cstrncmp(p + ccol, reginput, &len) != 0)
-                               {
-                                   status = RA_NOMATCH;  /* doesn't match */
-                                   break;
-                               }
-                               if (clnum == reg_endpos[no].lnum)
-                                   break;              /* match and at end! */
-                               if (reglnum >= reg_maxline)
-                               {
-                                   status = RA_NOMATCH;  /* text too short */
-                                   break;
-                               }
-
-                               /* Advance to next line. */
-                               reg_nextline();
-                               ++clnum;
-                               ccol = 0;
-                               if (got_int)
-                               {
-                                   status = RA_FAIL;
-                                   break;
-                               }
-                           }
-
-                           /* found a match!  Note that regline may now point
-                            * to a copy of the line, that should not matter. */
+                           status = match_with_backref(
+                                           reg_startpos[no].lnum,
+                                           reg_startpos[no].col,
+                                           reg_endpos[no].lnum,
+                                           reg_endpos[no].col,
+                                           NULL);
                        }
                    }
                }
@@ -6505,6 +6448,75 @@ re_num_cmp(val, scan)
     return val == n;
 }
 
+/*
+ * Check whether a backreference matches.
+ * Returns RA_FAIL, RA_NOMATCH or RA_MATCH.
+ * If "bytelen" is not NULL, it is set to the bytelength of the whole match.
+ */
+    static int
+match_with_backref(start_lnum, start_col, end_lnum, end_col, bytelen)
+    linenr_T start_lnum;
+    colnr_T  start_col;
+    linenr_T end_lnum;
+    colnr_T  end_col;
+    int             *bytelen;
+{
+    linenr_T   clnum = start_lnum;
+    colnr_T    ccol = start_col;
+    int                len;
+    char_u     *p;
+
+    if (bytelen != NULL)
+       *bytelen = 0;
+    for (;;)
+    {
+       /* Since getting one line may invalidate the other, need to make copy.
+        * Slow! */
+       if (regline != reg_tofree)
+       {
+           len = (int)STRLEN(regline);
+           if (reg_tofree == NULL || len >= (int)reg_tofreelen)
+           {
+               len += 50;      /* get some extra */
+               vim_free(reg_tofree);
+               reg_tofree = alloc(len);
+               if (reg_tofree == NULL)
+                   return RA_FAIL; /* out of memory!*/
+               reg_tofreelen = len;
+           }
+           STRCPY(reg_tofree, regline);
+           reginput = reg_tofree + (reginput - regline);
+           regline = reg_tofree;
+       }
+
+       /* Get the line to compare with. */
+       p = reg_getline(clnum);
+       if (clnum == end_lnum)
+           len = end_col - ccol;
+       else
+           len = (int)STRLEN(p + ccol);
+
+       if (cstrncmp(p + ccol, reginput, &len) != 0)
+           return RA_NOMATCH;  /* doesn't match */
+       if (bytelen != NULL)
+           *bytelen += len;
+       if (clnum == end_lnum)
+           break;              /* match and at end! */
+       if (reglnum >= reg_maxline)
+           return RA_NOMATCH;  /* text too short */
+
+       /* Advance to next line. */
+       reg_nextline();
+       ++clnum;
+       ccol = 0;
+       if (got_int)
+           return RA_FAIL;
+    }
+
+    /* found a match!  Note that regline may now point to a copy of the line,
+     * that should not matter. */
+    return RA_MATCH;
+}
 
 #ifdef BT_REGEXP_DUMP
 
index e843cd742c71381cab8a6b51035d81bade0a482a..702095548ff2b0a7fec98d7e7f354077da193dd0 100644 (file)
@@ -4367,14 +4367,27 @@ retempty:
        if (sub->list.multi[subidx].start.lnum < 0
                                       || sub->list.multi[subidx].end.lnum < 0)
            goto retempty;
-       /* TODO: line breaks */
-       len = sub->list.multi[subidx].end.col
-                                        - sub->list.multi[subidx].start.col;
-       if (cstrncmp(regline + sub->list.multi[subidx].start.col,
-                                                       reginput, &len) == 0)
+       if (sub->list.multi[subidx].start.lnum == reglnum
+                              && sub->list.multi[subidx].end.lnum == reglnum)
        {
-           *bytelen = len;
-           return TRUE;
+           len = sub->list.multi[subidx].end.col
+                                         - sub->list.multi[subidx].start.col;
+           if (cstrncmp(regline + sub->list.multi[subidx].start.col,
+                                                        reginput, &len) == 0)
+           {
+               *bytelen = len;
+               return TRUE;
+           }
+       }
+       else
+       {
+           if (match_with_backref(
+                       sub->list.multi[subidx].start.lnum,
+                       sub->list.multi[subidx].start.col,
+                       sub->list.multi[subidx].end.lnum,
+                       sub->list.multi[subidx].end.col,
+                       bytelen) == RA_MATCH)
+               return TRUE;
        }
     }
     else
index 51cdb31e8ee9c98538b16832c1fb0fc5f3f53db4..fe61ed3f26ef01d9c855cdc8b8c2afe8fea937e3 100644 (file)
@@ -486,6 +486,12 @@ y$Go\ep:"
 :.yank
 Go\ep:"
 :"
+:" Check using a backref matching in a previous line
+/^Backref:
+/\v.*\/(.*)\n.*\/\1$
+:.yank
+Go\ep:"
+:"
 :" Check a pattern with a look beind crossing a line boundary
 /^Behind:
 /\(<\_[xy]\+\)\@3<=start
@@ -566,6 +572,13 @@ a
 b
 c
 
+Backref:
+./Dir1/Dir2/zyxwvuts.txt
+./Dir1/Dir2/abcdefgh.bat
+
+./Dir1/Dir2/file1.txt
+./OtherDir1/OtherDir2/file1.txt
+
 Behind:
 asdfasd<yyy
 xxstart1
index 20725dde4297a7add329d142d4297ba55c1a4ed4..fe14fbd3ff88222feea1477d151e47d291b8add7 100644 (file)
@@ -920,6 +920,8 @@ ghi
 
 c
 
+./Dir1/Dir2/file1.txt
+
 xxstart3
 
 thexE thE thExethe
index ca9150940c91d9e6e36f971a041c90f75ef30a6a..8168890d2529988f2634f146f88ca6d1f192bb72 100644 (file)
@@ -728,6 +728,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1191,
 /**/
     1190,
 /**/