forked from aniani/vim
updated for version 7.3.1191
Problem: Backreference to previous line doesn't work. (Lech Lorens) Solution: Implement looking in another line.
This commit is contained in:
140
src/regexp.c
140
src/regexp.c
@@ -3519,6 +3519,7 @@ static void save_se_one __ARGS((save_se_T *savep, char_u **pp));
|
|||||||
*(pp) = (savep)->se_u.ptr; }
|
*(pp) = (savep)->se_u.ptr; }
|
||||||
|
|
||||||
static int re_num_cmp __ARGS((long_u val, char_u *scan));
|
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 regmatch __ARGS((char_u *prog));
|
||||||
static int regrepeat __ARGS((char_u *p, long maxcount));
|
static int regrepeat __ARGS((char_u *p, long maxcount));
|
||||||
|
|
||||||
@@ -4979,9 +4980,6 @@ regmatch(scan)
|
|||||||
case BACKREF + 9:
|
case BACKREF + 9:
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
linenr_T clnum;
|
|
||||||
colnr_T ccol;
|
|
||||||
char_u *p;
|
|
||||||
|
|
||||||
no = op - BACKREF;
|
no = op - BACKREF;
|
||||||
cleanup_subexpr();
|
cleanup_subexpr();
|
||||||
@@ -5023,67 +5021,12 @@ regmatch(scan)
|
|||||||
{
|
{
|
||||||
/* Messy situation: Need to compare between two
|
/* Messy situation: Need to compare between two
|
||||||
* lines. */
|
* lines. */
|
||||||
ccol = reg_startpos[no].col;
|
status = match_with_backref(
|
||||||
clnum = reg_startpos[no].lnum;
|
reg_startpos[no].lnum,
|
||||||
for (;;)
|
reg_startpos[no].col,
|
||||||
{
|
reg_endpos[no].lnum,
|
||||||
/* Since getting one line may invalidate
|
reg_endpos[no].col,
|
||||||
* the other, need to make copy. Slow! */
|
NULL);
|
||||||
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. */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6505,6 +6448,75 @@ re_num_cmp(val, scan)
|
|||||||
return val == n;
|
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
|
#ifdef BT_REGEXP_DUMP
|
||||||
|
|
||||||
|
@@ -4367,14 +4367,27 @@ retempty:
|
|||||||
if (sub->list.multi[subidx].start.lnum < 0
|
if (sub->list.multi[subidx].start.lnum < 0
|
||||||
|| sub->list.multi[subidx].end.lnum < 0)
|
|| sub->list.multi[subidx].end.lnum < 0)
|
||||||
goto retempty;
|
goto retempty;
|
||||||
/* TODO: line breaks */
|
if (sub->list.multi[subidx].start.lnum == reglnum
|
||||||
len = sub->list.multi[subidx].end.col
|
&& sub->list.multi[subidx].end.lnum == reglnum)
|
||||||
- sub->list.multi[subidx].start.col;
|
|
||||||
if (cstrncmp(regline + sub->list.multi[subidx].start.col,
|
|
||||||
reginput, &len) == 0)
|
|
||||||
{
|
{
|
||||||
*bytelen = len;
|
len = sub->list.multi[subidx].end.col
|
||||||
return TRUE;
|
- 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
|
else
|
||||||
|
@@ -486,6 +486,12 @@ y$Gop:"
|
|||||||
:.yank
|
:.yank
|
||||||
Gop:"
|
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
|
:" Check a pattern with a look beind crossing a line boundary
|
||||||
/^Behind:
|
/^Behind:
|
||||||
/\(<\_[xy]\+\)\@3<=start
|
/\(<\_[xy]\+\)\@3<=start
|
||||||
@@ -566,6 +572,13 @@ a
|
|||||||
b
|
b
|
||||||
c
|
c
|
||||||
|
|
||||||
|
Backref:
|
||||||
|
./Dir1/Dir2/zyxwvuts.txt
|
||||||
|
./Dir1/Dir2/abcdefgh.bat
|
||||||
|
|
||||||
|
./Dir1/Dir2/file1.txt
|
||||||
|
./OtherDir1/OtherDir2/file1.txt
|
||||||
|
|
||||||
Behind:
|
Behind:
|
||||||
asdfasd<yyy
|
asdfasd<yyy
|
||||||
xxstart1
|
xxstart1
|
||||||
|
@@ -920,6 +920,8 @@ ghi
|
|||||||
|
|
||||||
c
|
c
|
||||||
|
|
||||||
|
./Dir1/Dir2/file1.txt
|
||||||
|
|
||||||
xxstart3
|
xxstart3
|
||||||
|
|
||||||
thexE thE thExethe
|
thexE thE thExethe
|
||||||
|
@@ -728,6 +728,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1191,
|
||||||
/**/
|
/**/
|
||||||
1190,
|
1190,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user