312 lines
8.0 KiB
Plaintext
312 lines
8.0 KiB
Plaintext
|
To: vim_dev@googlegroups.com
|
|||
|
Subject: Patch 7.3.1191
|
|||
|
Fcc: outbox
|
|||
|
From: Bram Moolenaar <Bram@moolenaar.net>
|
|||
|
Mime-Version: 1.0
|
|||
|
Content-Type: text/plain; charset=UTF-8
|
|||
|
Content-Transfer-Encoding: 8bit
|
|||
|
------------
|
|||
|
|
|||
|
Patch 7.3.1191
|
|||
|
Problem: Backreference to previous line doesn't work. (Lech Lorens)
|
|||
|
Solution: Implement looking in another line.
|
|||
|
Files: src/regexp.c, src/regexp_nfa.c, src/testdir/test64.in,
|
|||
|
src/testdir/test64.ok
|
|||
|
|
|||
|
|
|||
|
*** ../vim-7.3.1190/src/regexp.c 2013-06-08 18:19:39.000000000 +0200
|
|||
|
--- src/regexp.c 2013-06-14 20:23:33.000000000 +0200
|
|||
|
***************
|
|||
|
*** 3519,3524 ****
|
|||
|
--- 3519,3525 ----
|
|||
|
*(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,4987 ****
|
|||
|
case BACKREF + 9:
|
|||
|
{
|
|||
|
int len;
|
|||
|
- linenr_T clnum;
|
|||
|
- colnr_T ccol;
|
|||
|
- char_u *p;
|
|||
|
|
|||
|
no = op - BACKREF;
|
|||
|
cleanup_subexpr();
|
|||
|
--- 4980,4985 ----
|
|||
|
***************
|
|||
|
*** 5023,5089 ****
|
|||
|
{
|
|||
|
/* 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. */
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
--- 5021,5032 ----
|
|||
|
{
|
|||
|
/* Messy situation: Need to compare between two
|
|||
|
* lines. */
|
|||
|
! status = match_with_backref(
|
|||
|
! reg_startpos[no].lnum,
|
|||
|
! reg_startpos[no].col,
|
|||
|
! reg_endpos[no].lnum,
|
|||
|
! reg_endpos[no].col,
|
|||
|
! NULL);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
***************
|
|||
|
*** 6505,6510 ****
|
|||
|
--- 6448,6522 ----
|
|||
|
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
|
|||
|
|
|||
|
*** ../vim-7.3.1190/src/regexp_nfa.c 2013-06-13 22:59:25.000000000 +0200
|
|||
|
--- src/regexp_nfa.c 2013-06-14 20:19:59.000000000 +0200
|
|||
|
***************
|
|||
|
*** 4367,4380 ****
|
|||
|
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)
|
|||
|
{
|
|||
|
! *bytelen = len;
|
|||
|
! return TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
--- 4367,4393 ----
|
|||
|
if (sub->list.multi[subidx].start.lnum < 0
|
|||
|
|| sub->list.multi[subidx].end.lnum < 0)
|
|||
|
goto retempty;
|
|||
|
! if (sub->list.multi[subidx].start.lnum == reglnum
|
|||
|
! && sub->list.multi[subidx].end.lnum == reglnum)
|
|||
|
{
|
|||
|
! 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
|
|||
|
*** ../vim-7.3.1190/src/testdir/test64.in 2013-06-13 20:19:35.000000000 +0200
|
|||
|
--- src/testdir/test64.in 2013-06-14 20:01:56.000000000 +0200
|
|||
|
***************
|
|||
|
*** 486,491 ****
|
|||
|
--- 486,497 ----
|
|||
|
:.yank
|
|||
|
Gop:"
|
|||
|
:"
|
|||
|
+ :" Check using a backref matching in a previous line
|
|||
|
+ /^Backref:
|
|||
|
+ /\v.*\/(.*)\n.*\/\1$
|
|||
|
+ :.yank
|
|||
|
+ Gop:"
|
|||
|
+ :"
|
|||
|
:" Check a pattern with a look beind crossing a line boundary
|
|||
|
/^Behind:
|
|||
|
/\(<\_[xy]\+\)\@3<=start
|
|||
|
***************
|
|||
|
*** 566,571 ****
|
|||
|
--- 572,584 ----
|
|||
|
b
|
|||
|
c
|
|||
|
|
|||
|
+ Backref:
|
|||
|
+ ./Dir1/Dir2/zyxwvuts.txt
|
|||
|
+ ./Dir1/Dir2/abcdefgh.bat
|
|||
|
+
|
|||
|
+ ./Dir1/Dir2/file1.txt
|
|||
|
+ ./OtherDir1/OtherDir2/file1.txt
|
|||
|
+
|
|||
|
Behind:
|
|||
|
asdfasd<yyy
|
|||
|
xxstart1
|
|||
|
*** ../vim-7.3.1190/src/testdir/test64.ok 2013-06-13 20:19:35.000000000 +0200
|
|||
|
--- src/testdir/test64.ok 2013-06-14 20:02:44.000000000 +0200
|
|||
|
***************
|
|||
|
*** 920,925 ****
|
|||
|
--- 920,927 ----
|
|||
|
|
|||
|
c
|
|||
|
|
|||
|
+ ./Dir1/Dir2/file1.txt
|
|||
|
+
|
|||
|
xxstart3
|
|||
|
|
|||
|
thexE thE thExethe
|
|||
|
*** ../vim-7.3.1190/src/version.c 2013-06-14 19:15:52.000000000 +0200
|
|||
|
--- src/version.c 2013-06-14 20:30:34.000000000 +0200
|
|||
|
***************
|
|||
|
*** 730,731 ****
|
|||
|
--- 730,733 ----
|
|||
|
{ /* Add new patch number below this line */
|
|||
|
+ /**/
|
|||
|
+ 1191,
|
|||
|
/**/
|
|||
|
|
|||
|
--
|
|||
|
hundred-and-one symptoms of being an internet addict:
|
|||
|
198. You read all the quotes at Netaholics Anonymous and keep thinking
|
|||
|
"What's wrong with that?"
|
|||
|
|
|||
|
/// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
|
|||
|
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
|
|||
|
\\\ an exciting new programming language -- http://www.Zimbu.org ///
|
|||
|
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
|