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 ///
|