vim/7.3.1191
2013-07-04 15:35:50 +02:00

312 lines
8.0 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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