Karsten Hopp b5df12
To: vim_dev@googlegroups.com
Karsten Hopp b5df12
Subject: Patch 7.3.1191
Karsten Hopp b5df12
Fcc: outbox
Karsten Hopp b5df12
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp b5df12
Mime-Version: 1.0
Karsten Hopp b5df12
Content-Type: text/plain; charset=UTF-8
Karsten Hopp b5df12
Content-Transfer-Encoding: 8bit
Karsten Hopp b5df12
------------
Karsten Hopp b5df12
Karsten Hopp b5df12
Patch 7.3.1191
Karsten Hopp b5df12
Problem:    Backreference to previous line doesn't work. (Lech Lorens)
Karsten Hopp b5df12
Solution:   Implement looking in another line.
Karsten Hopp b5df12
Files:	    src/regexp.c, src/regexp_nfa.c, src/testdir/test64.in,
Karsten Hopp b5df12
	    src/testdir/test64.ok
Karsten Hopp b5df12
Karsten Hopp b5df12
Karsten Hopp b5df12
*** ../vim-7.3.1190/src/regexp.c	2013-06-08 18:19:39.000000000 +0200
Karsten Hopp b5df12
--- src/regexp.c	2013-06-14 20:23:33.000000000 +0200
Karsten Hopp b5df12
***************
Karsten Hopp b5df12
*** 3519,3524 ****
Karsten Hopp b5df12
--- 3519,3525 ----
Karsten Hopp b5df12
  	*(pp) = (savep)->se_u.ptr; }
Karsten Hopp b5df12
  
Karsten Hopp b5df12
  static int	re_num_cmp __ARGS((long_u val, char_u *scan));
Karsten Hopp b5df12
+ static int	match_with_backref __ARGS((linenr_T start_lnum, colnr_T start_col, linenr_T end_lnum, colnr_T end_col, int *bytelen));
Karsten Hopp b5df12
  static int	regmatch __ARGS((char_u *prog));
Karsten Hopp b5df12
  static int	regrepeat __ARGS((char_u *p, long maxcount));
Karsten Hopp b5df12
  
Karsten Hopp b5df12
***************
Karsten Hopp b5df12
*** 4979,4987 ****
Karsten Hopp b5df12
  	  case BACKREF + 9:
Karsten Hopp b5df12
  	    {
Karsten Hopp b5df12
  		int		len;
Karsten Hopp b5df12
- 		linenr_T	clnum;
Karsten Hopp b5df12
- 		colnr_T		ccol;
Karsten Hopp b5df12
- 		char_u		*p;
Karsten Hopp b5df12
  
Karsten Hopp b5df12
  		no = op - BACKREF;
Karsten Hopp b5df12
  		cleanup_subexpr();
Karsten Hopp b5df12
--- 4980,4985 ----
Karsten Hopp b5df12
***************
Karsten Hopp b5df12
*** 5023,5089 ****
Karsten Hopp b5df12
  			{
Karsten Hopp b5df12
  			    /* Messy situation: Need to compare between two
Karsten Hopp b5df12
  			     * lines. */
Karsten Hopp b5df12
! 			    ccol = reg_startpos[no].col;
Karsten Hopp b5df12
! 			    clnum = reg_startpos[no].lnum;
Karsten Hopp b5df12
! 			    for (;;)
Karsten Hopp b5df12
! 			    {
Karsten Hopp b5df12
! 				/* Since getting one line may invalidate
Karsten Hopp b5df12
! 				 * the other, need to make copy.  Slow! */
Karsten Hopp b5df12
! 				if (regline != reg_tofree)
Karsten Hopp b5df12
! 				{
Karsten Hopp b5df12
! 				    len = (int)STRLEN(regline);
Karsten Hopp b5df12
! 				    if (reg_tofree == NULL
Karsten Hopp b5df12
! 						 || len >= (int)reg_tofreelen)
Karsten Hopp b5df12
! 				    {
Karsten Hopp b5df12
! 					len += 50;	/* get some extra */
Karsten Hopp b5df12
! 					vim_free(reg_tofree);
Karsten Hopp b5df12
! 					reg_tofree = alloc(len);
Karsten Hopp b5df12
! 					if (reg_tofree == NULL)
Karsten Hopp b5df12
! 					{
Karsten Hopp b5df12
! 					    status = RA_FAIL; /* outof memory!*/
Karsten Hopp b5df12
! 					    break;
Karsten Hopp b5df12
! 					}
Karsten Hopp b5df12
! 					reg_tofreelen = len;
Karsten Hopp b5df12
! 				    }
Karsten Hopp b5df12
! 				    STRCPY(reg_tofree, regline);
Karsten Hopp b5df12
! 				    reginput = reg_tofree
Karsten Hopp b5df12
! 						       + (reginput - regline);
Karsten Hopp b5df12
! 				    regline = reg_tofree;
Karsten Hopp b5df12
! 				}
Karsten Hopp b5df12
! 
Karsten Hopp b5df12
! 				/* Get the line to compare with. */
Karsten Hopp b5df12
! 				p = reg_getline(clnum);
Karsten Hopp b5df12
! 				if (clnum == reg_endpos[no].lnum)
Karsten Hopp b5df12
! 				    len = reg_endpos[no].col - ccol;
Karsten Hopp b5df12
! 				else
Karsten Hopp b5df12
! 				    len = (int)STRLEN(p + ccol);
Karsten Hopp b5df12
! 
Karsten Hopp b5df12
! 				if (cstrncmp(p + ccol, reginput, &len) != 0)
Karsten Hopp b5df12
! 				{
Karsten Hopp b5df12
! 				    status = RA_NOMATCH;  /* doesn't match */
Karsten Hopp b5df12
! 				    break;
Karsten Hopp b5df12
! 				}
Karsten Hopp b5df12
! 				if (clnum == reg_endpos[no].lnum)
Karsten Hopp b5df12
! 				    break;		/* match and at end! */
Karsten Hopp b5df12
! 				if (reglnum >= reg_maxline)
Karsten Hopp b5df12
! 				{
Karsten Hopp b5df12
! 				    status = RA_NOMATCH;  /* text too short */
Karsten Hopp b5df12
! 				    break;
Karsten Hopp b5df12
! 				}
Karsten Hopp b5df12
! 
Karsten Hopp b5df12
! 				/* Advance to next line. */
Karsten Hopp b5df12
! 				reg_nextline();
Karsten Hopp b5df12
! 				++clnum;
Karsten Hopp b5df12
! 				ccol = 0;
Karsten Hopp b5df12
! 				if (got_int)
Karsten Hopp b5df12
! 				{
Karsten Hopp b5df12
! 				    status = RA_FAIL;
Karsten Hopp b5df12
! 				    break;
Karsten Hopp b5df12
! 				}
Karsten Hopp b5df12
! 			    }
Karsten Hopp b5df12
! 
Karsten Hopp b5df12
! 			    /* found a match!  Note that regline may now point
Karsten Hopp b5df12
! 			     * to a copy of the line, that should not matter. */
Karsten Hopp b5df12
  			}
Karsten Hopp b5df12
  		    }
Karsten Hopp b5df12
  		}
Karsten Hopp b5df12
--- 5021,5032 ----
Karsten Hopp b5df12
  			{
Karsten Hopp b5df12
  			    /* Messy situation: Need to compare between two
Karsten Hopp b5df12
  			     * lines. */
Karsten Hopp b5df12
! 			    status = match_with_backref(
Karsten Hopp b5df12
! 					    reg_startpos[no].lnum,
Karsten Hopp b5df12
! 					    reg_startpos[no].col,
Karsten Hopp b5df12
! 					    reg_endpos[no].lnum,
Karsten Hopp b5df12
! 					    reg_endpos[no].col,
Karsten Hopp b5df12
! 					    NULL);
Karsten Hopp b5df12
  			}
Karsten Hopp b5df12
  		    }
Karsten Hopp b5df12
  		}
Karsten Hopp b5df12
***************
Karsten Hopp b5df12
*** 6505,6510 ****
Karsten Hopp b5df12
--- 6448,6522 ----
Karsten Hopp b5df12
      return val == n;
Karsten Hopp b5df12
  }
Karsten Hopp b5df12
  
Karsten Hopp b5df12
+ /*
Karsten Hopp b5df12
+  * Check whether a backreference matches.
Karsten Hopp b5df12
+  * Returns RA_FAIL, RA_NOMATCH or RA_MATCH.
Karsten Hopp b5df12
+  * If "bytelen" is not NULL, it is set to the bytelength of the whole match.
Karsten Hopp b5df12
+  */
Karsten Hopp b5df12
+     static int
Karsten Hopp b5df12
+ match_with_backref(start_lnum, start_col, end_lnum, end_col, bytelen)
Karsten Hopp b5df12
+     linenr_T start_lnum;
Karsten Hopp b5df12
+     colnr_T  start_col;
Karsten Hopp b5df12
+     linenr_T end_lnum;
Karsten Hopp b5df12
+     colnr_T  end_col;
Karsten Hopp b5df12
+     int	     *bytelen;
Karsten Hopp b5df12
+ {
Karsten Hopp b5df12
+     linenr_T	clnum = start_lnum;
Karsten Hopp b5df12
+     colnr_T	ccol = start_col;
Karsten Hopp b5df12
+     int		len;
Karsten Hopp b5df12
+     char_u	*p;
Karsten Hopp b5df12
+ 
Karsten Hopp b5df12
+     if (bytelen != NULL)
Karsten Hopp b5df12
+ 	*bytelen = 0;
Karsten Hopp b5df12
+     for (;;)
Karsten Hopp b5df12
+     {
Karsten Hopp b5df12
+ 	/* Since getting one line may invalidate the other, need to make copy.
Karsten Hopp b5df12
+ 	 * Slow! */
Karsten Hopp b5df12
+ 	if (regline != reg_tofree)
Karsten Hopp b5df12
+ 	{
Karsten Hopp b5df12
+ 	    len = (int)STRLEN(regline);
Karsten Hopp b5df12
+ 	    if (reg_tofree == NULL || len >= (int)reg_tofreelen)
Karsten Hopp b5df12
+ 	    {
Karsten Hopp b5df12
+ 		len += 50;	/* get some extra */
Karsten Hopp b5df12
+ 		vim_free(reg_tofree);
Karsten Hopp b5df12
+ 		reg_tofree = alloc(len);
Karsten Hopp b5df12
+ 		if (reg_tofree == NULL)
Karsten Hopp b5df12
+ 		    return RA_FAIL; /* out of memory!*/
Karsten Hopp b5df12
+ 		reg_tofreelen = len;
Karsten Hopp b5df12
+ 	    }
Karsten Hopp b5df12
+ 	    STRCPY(reg_tofree, regline);
Karsten Hopp b5df12
+ 	    reginput = reg_tofree + (reginput - regline);
Karsten Hopp b5df12
+ 	    regline = reg_tofree;
Karsten Hopp b5df12
+ 	}
Karsten Hopp b5df12
+ 
Karsten Hopp b5df12
+ 	/* Get the line to compare with. */
Karsten Hopp b5df12
+ 	p = reg_getline(clnum);
Karsten Hopp b5df12
+ 	if (clnum == end_lnum)
Karsten Hopp b5df12
+ 	    len = end_col - ccol;
Karsten Hopp b5df12
+ 	else
Karsten Hopp b5df12
+ 	    len = (int)STRLEN(p + ccol);
Karsten Hopp b5df12
+ 
Karsten Hopp b5df12
+ 	if (cstrncmp(p + ccol, reginput, &len) != 0)
Karsten Hopp b5df12
+ 	    return RA_NOMATCH;  /* doesn't match */
Karsten Hopp b5df12
+ 	if (bytelen != NULL)
Karsten Hopp b5df12
+ 	    *bytelen += len;
Karsten Hopp b5df12
+ 	if (clnum == end_lnum)
Karsten Hopp b5df12
+ 	    break;		/* match and at end! */
Karsten Hopp b5df12
+ 	if (reglnum >= reg_maxline)
Karsten Hopp b5df12
+ 	    return RA_NOMATCH;  /* text too short */
Karsten Hopp b5df12
+ 
Karsten Hopp b5df12
+ 	/* Advance to next line. */
Karsten Hopp b5df12
+ 	reg_nextline();
Karsten Hopp b5df12
+ 	++clnum;
Karsten Hopp b5df12
+ 	ccol = 0;
Karsten Hopp b5df12
+ 	if (got_int)
Karsten Hopp b5df12
+ 	    return RA_FAIL;
Karsten Hopp b5df12
+     }
Karsten Hopp b5df12
+ 
Karsten Hopp b5df12
+     /* found a match!  Note that regline may now point to a copy of the line,
Karsten Hopp b5df12
+      * that should not matter. */
Karsten Hopp b5df12
+     return RA_MATCH;
Karsten Hopp b5df12
+ }
Karsten Hopp b5df12
  
Karsten Hopp b5df12
  #ifdef BT_REGEXP_DUMP
Karsten Hopp b5df12
  
Karsten Hopp b5df12
*** ../vim-7.3.1190/src/regexp_nfa.c	2013-06-13 22:59:25.000000000 +0200
Karsten Hopp b5df12
--- src/regexp_nfa.c	2013-06-14 20:19:59.000000000 +0200
Karsten Hopp b5df12
***************
Karsten Hopp b5df12
*** 4367,4380 ****
Karsten Hopp b5df12
  	if (sub->list.multi[subidx].start.lnum < 0
Karsten Hopp b5df12
  				       || sub->list.multi[subidx].end.lnum < 0)
Karsten Hopp b5df12
  	    goto retempty;
Karsten Hopp b5df12
! 	/* TODO: line breaks */
Karsten Hopp b5df12
! 	len = sub->list.multi[subidx].end.col
Karsten Hopp b5df12
! 					 - sub->list.multi[subidx].start.col;
Karsten Hopp b5df12
! 	if (cstrncmp(regline + sub->list.multi[subidx].start.col,
Karsten Hopp b5df12
! 							reginput, &len) == 0)
Karsten Hopp b5df12
  	{
Karsten Hopp b5df12
! 	    *bytelen = len;
Karsten Hopp b5df12
! 	    return TRUE;
Karsten Hopp b5df12
  	}
Karsten Hopp b5df12
      }
Karsten Hopp b5df12
      else
Karsten Hopp b5df12
--- 4367,4393 ----
Karsten Hopp b5df12
  	if (sub->list.multi[subidx].start.lnum < 0
Karsten Hopp b5df12
  				       || sub->list.multi[subidx].end.lnum < 0)
Karsten Hopp b5df12
  	    goto retempty;
Karsten Hopp b5df12
! 	if (sub->list.multi[subidx].start.lnum == reglnum
Karsten Hopp b5df12
! 			       && sub->list.multi[subidx].end.lnum == reglnum)
Karsten Hopp b5df12
  	{
Karsten Hopp b5df12
! 	    len = sub->list.multi[subidx].end.col
Karsten Hopp b5df12
! 					  - sub->list.multi[subidx].start.col;
Karsten Hopp b5df12
! 	    if (cstrncmp(regline + sub->list.multi[subidx].start.col,
Karsten Hopp b5df12
! 							 reginput, &len) == 0)
Karsten Hopp b5df12
! 	    {
Karsten Hopp b5df12
! 		*bytelen = len;
Karsten Hopp b5df12
! 		return TRUE;
Karsten Hopp b5df12
! 	    }
Karsten Hopp b5df12
! 	}
Karsten Hopp b5df12
! 	else
Karsten Hopp b5df12
! 	{
Karsten Hopp b5df12
! 	    if (match_with_backref(
Karsten Hopp b5df12
! 			sub->list.multi[subidx].start.lnum,
Karsten Hopp b5df12
! 			sub->list.multi[subidx].start.col,
Karsten Hopp b5df12
! 			sub->list.multi[subidx].end.lnum,
Karsten Hopp b5df12
! 			sub->list.multi[subidx].end.col,
Karsten Hopp b5df12
! 			bytelen) == RA_MATCH)
Karsten Hopp b5df12
! 		return TRUE;
Karsten Hopp b5df12
  	}
Karsten Hopp b5df12
      }
Karsten Hopp b5df12
      else
Karsten Hopp b5df12
*** ../vim-7.3.1190/src/testdir/test64.in	2013-06-13 20:19:35.000000000 +0200
Karsten Hopp b5df12
--- src/testdir/test64.in	2013-06-14 20:01:56.000000000 +0200
Karsten Hopp b5df12
***************
Karsten Hopp b5df12
*** 486,491 ****
Karsten Hopp b5df12
--- 486,497 ----
Karsten Hopp b5df12
  :.yank
Karsten Hopp b5df12
  Go?p:"
Karsten Hopp b5df12
  :"
Karsten Hopp b5df12
+ :" Check using a backref matching in a previous line
Karsten Hopp b5df12
+ /^Backref:
Karsten Hopp b5df12
+ /\v.*\/(.*)\n.*\/\1$
Karsten Hopp b5df12
+ :.yank
Karsten Hopp b5df12
+ Go?p:"
Karsten Hopp b5df12
+ :"
Karsten Hopp b5df12
  :" Check a pattern with a look beind crossing a line boundary
Karsten Hopp b5df12
  /^Behind:
Karsten Hopp b5df12
  /\(<\_[xy]\+\)\@3<=start
Karsten Hopp b5df12
***************
Karsten Hopp b5df12
*** 566,571 ****
Karsten Hopp b5df12
--- 572,584 ----
Karsten Hopp b5df12
  b
Karsten Hopp b5df12
  c
Karsten Hopp b5df12
  
Karsten Hopp b5df12
+ Backref:
Karsten Hopp b5df12
+ ./Dir1/Dir2/zyxwvuts.txt
Karsten Hopp b5df12
+ ./Dir1/Dir2/abcdefgh.bat
Karsten Hopp b5df12
+ 
Karsten Hopp b5df12
+ ./Dir1/Dir2/file1.txt
Karsten Hopp b5df12
+ ./OtherDir1/OtherDir2/file1.txt
Karsten Hopp b5df12
+ 
Karsten Hopp b5df12
  Behind:
Karsten Hopp b5df12
  asdfasd
Karsten Hopp b5df12
  xxstart1
Karsten Hopp b5df12
*** ../vim-7.3.1190/src/testdir/test64.ok	2013-06-13 20:19:35.000000000 +0200
Karsten Hopp b5df12
--- src/testdir/test64.ok	2013-06-14 20:02:44.000000000 +0200
Karsten Hopp b5df12
***************
Karsten Hopp b5df12
*** 920,925 ****
Karsten Hopp b5df12
--- 920,927 ----
Karsten Hopp b5df12
  
Karsten Hopp b5df12
  c
Karsten Hopp b5df12
  
Karsten Hopp b5df12
+ ./Dir1/Dir2/file1.txt
Karsten Hopp b5df12
+ 
Karsten Hopp b5df12
  xxstart3
Karsten Hopp b5df12
  
Karsten Hopp b5df12
  thexE thE thExethe
Karsten Hopp b5df12
*** ../vim-7.3.1190/src/version.c	2013-06-14 19:15:52.000000000 +0200
Karsten Hopp b5df12
--- src/version.c	2013-06-14 20:30:34.000000000 +0200
Karsten Hopp b5df12
***************
Karsten Hopp b5df12
*** 730,731 ****
Karsten Hopp b5df12
--- 730,733 ----
Karsten Hopp b5df12
  {   /* Add new patch number below this line */
Karsten Hopp b5df12
+ /**/
Karsten Hopp b5df12
+     1191,
Karsten Hopp b5df12
  /**/
Karsten Hopp b5df12
Karsten Hopp b5df12
-- 
Karsten Hopp b5df12
hundred-and-one symptoms of being an internet addict:
Karsten Hopp b5df12
198. You read all the quotes at Netaholics Anonymous and keep thinking
Karsten Hopp b5df12
     "What's wrong with that?"
Karsten Hopp b5df12
Karsten Hopp b5df12
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp b5df12
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp b5df12
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp b5df12
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///