To: vim_dev@googlegroups.com
Subject: Patch 7.3.180
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.180
Problem:    When both a middle part of 'comments' matches and an end part, the
	    middle part was used errornously.
Solution:   After finding the middle part match continue looking for a better
	    end part match. (partly by Lech Lorens)
Files:	    src/misc1.c, src/testdir/test3.in, src/testdir/test3.ok


*** ../vim-7.3.179/src/misc1.c	2011-05-10 11:56:26.000000000 +0200
--- src/misc1.c	2011-05-10 13:24:38.000000000 +0200
***************
*** 1561,1566 ****
--- 1561,1569 ----
      char_u	part_buf[COM_MAX_LEN];	/* buffer for one option part */
      char_u	*string;		/* pointer to comment string */
      char_u	*list;
+     int		middle_match_len = 0;
+     char_u	*prev_list;
+     char_u	*saved_flags;
  
      i = 0;
      while (vim_iswhite(line[i]))    /* leading white space is ignored */
***************
*** 1569,1575 ****
      /*
       * Repeat to match several nested comment strings.
       */
!     while (line[i])
      {
  	/*
  	 * scan through the 'comments' option for a match
--- 1572,1578 ----
      /*
       * Repeat to match several nested comment strings.
       */
!     while (line[i] != NUL)
      {
  	/*
  	 * scan through the 'comments' option for a match
***************
*** 1577,1658 ****
  	found_one = FALSE;
  	for (list = curbuf->b_p_com; *list; )
  	{
! 	    /*
! 	     * Get one option part into part_buf[].  Advance list to next one.
! 	     * put string at start of string.
! 	     */
! 	    if (!got_com && flags != NULL)  /* remember where flags started */
! 		*flags = list;
  	    (void)copy_option_part(&list, part_buf, COM_MAX_LEN, ",");
  	    string = vim_strchr(part_buf, ':');
  	    if (string == NULL)	    /* missing ':', ignore this part */
  		continue;
  	    *string++ = NUL;	    /* isolate flags from string */
  
! 	    /*
! 	     * When already found a nested comment, only accept further
! 	     * nested comments.
! 	     */
  	    if (got_com && vim_strchr(part_buf, COM_NEST) == NULL)
  		continue;
  
! 	    /* When 'O' flag used don't use for "O" command */
  	    if (backward && vim_strchr(part_buf, COM_NOBACK) != NULL)
  		continue;
  
! 	    /*
! 	     * Line contents and string must match.
  	     * When string starts with white space, must have some white space
  	     * (but the amount does not need to match, there might be a mix of
! 	     * TABs and spaces).
! 	     */
  	    if (vim_iswhite(string[0]))
  	    {
  		if (i == 0 || !vim_iswhite(line[i - 1]))
! 		    continue;
  		while (vim_iswhite(string[0]))
  		    ++string;
  	    }
  	    for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
  		;
  	    if (string[j] != NUL)
! 		continue;
  
! 	    /*
! 	     * When 'b' flag used, there must be white space or an
! 	     * end-of-line after the string in the line.
! 	     */
  	    if (vim_strchr(part_buf, COM_BLANK) != NULL
  			   && !vim_iswhite(line[i + j]) && line[i + j] != NUL)
  		continue;
  
! 	    /*
! 	     * We have found a match, stop searching.
! 	     */
! 	    i += j;
! 	    got_com = TRUE;
  	    found_one = TRUE;
  	    break;
  	}
  
! 	/*
! 	 * No match found, stop scanning.
! 	 */
  	if (!found_one)
  	    break;
  
! 	/*
! 	 * Include any trailing white space.
! 	 */
  	while (vim_iswhite(line[i]))
  	    ++i;
  
! 	/*
! 	 * If this comment doesn't nest, stop here.
! 	 */
  	if (vim_strchr(part_buf, COM_NEST) == NULL)
  	    break;
      }
      return (got_com ? i : 0);
  }
  #endif
--- 1580,1683 ----
  	found_one = FALSE;
  	for (list = curbuf->b_p_com; *list; )
  	{
! 	    /* Get one option part into part_buf[].  Advance "list" to next
! 	     * one.  Put "string" at start of string.  */
! 	    if (!got_com && flags != NULL)
! 		*flags = list;	    /* remember where flags started */
! 	    prev_list = list;
  	    (void)copy_option_part(&list, part_buf, COM_MAX_LEN, ",");
  	    string = vim_strchr(part_buf, ':');
  	    if (string == NULL)	    /* missing ':', ignore this part */
  		continue;
  	    *string++ = NUL;	    /* isolate flags from string */
  
! 	    /* If we found a middle match previously, use that match when this
! 	     * is not a middle or end. */
! 	    if (middle_match_len != 0
! 		    && vim_strchr(part_buf, COM_MIDDLE) == NULL
! 		    && vim_strchr(part_buf, COM_END) == NULL)
! 		break;
! 
! 	    /* When we already found a nested comment, only accept further
! 	     * nested comments. */
  	    if (got_com && vim_strchr(part_buf, COM_NEST) == NULL)
  		continue;
  
! 	    /* When 'O' flag present and using "O" command skip this one. */
  	    if (backward && vim_strchr(part_buf, COM_NOBACK) != NULL)
  		continue;
  
! 	    /* Line contents and string must match.
  	     * When string starts with white space, must have some white space
  	     * (but the amount does not need to match, there might be a mix of
! 	     * TABs and spaces). */
  	    if (vim_iswhite(string[0]))
  	    {
  		if (i == 0 || !vim_iswhite(line[i - 1]))
! 		    continue;  /* missing shite space */
  		while (vim_iswhite(string[0]))
  		    ++string;
  	    }
  	    for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
  		;
  	    if (string[j] != NUL)
! 		continue;  /* string doesn't match */
  
! 	    /* When 'b' flag used, there must be white space or an
! 	     * end-of-line after the string in the line. */
  	    if (vim_strchr(part_buf, COM_BLANK) != NULL
  			   && !vim_iswhite(line[i + j]) && line[i + j] != NUL)
  		continue;
  
! 	    /* We have found a match, stop searching unless this is a middle
! 	     * comment. The middle comment can be a substring of the end
! 	     * comment in which case it's better to return the length of the
! 	     * end comment and its flags.  Thus we keep searching with middle
! 	     * and end matches and use an end match if it matches better. */
! 	    if (vim_strchr(part_buf, COM_MIDDLE) != NULL)
! 	    {
! 		if (middle_match_len == 0)
! 		{
! 		    middle_match_len = j;
! 		    saved_flags = prev_list;
! 		}
! 		continue;
! 	    }
! 	    if (middle_match_len != 0 && j > middle_match_len)
! 		/* Use this match instead of the middle match, since it's a
! 		 * longer thus better match. */
! 		middle_match_len = 0;
! 
! 	    if (middle_match_len == 0)
! 		i += j;
  	    found_one = TRUE;
  	    break;
  	}
  
! 	if (middle_match_len != 0)
! 	{
! 	    /* Use the previously found middle match after failing to find a
! 	     * match with an end. */
! 	    if (!got_com && flags != NULL)
! 		*flags = saved_flags;
! 	    i += middle_match_len;
! 	    found_one = TRUE;
! 	}
! 
! 	/* No match found, stop scanning. */
  	if (!found_one)
  	    break;
  
! 	/* Include any trailing white space. */
  	while (vim_iswhite(line[i]))
  	    ++i;
  
! 	/* If this comment doesn't nest, stop here. */
! 	got_com = TRUE;
  	if (vim_strchr(part_buf, COM_NEST) == NULL)
  	    break;
      }
+ 
      return (got_com ? i : 0);
  }
  #endif
*** ../vim-7.3.179/src/testdir/test3.in	2011-05-10 11:56:26.000000000 +0200
--- src/testdir/test3.in	2011-05-10 12:05:50.000000000 +0200
***************
*** 1373,1378 ****
--- 1373,1390 ----
  }
  
  STARTTEST
+ :set com=s1:/*,m:*,ex:*/
+ ]]3jofoo();
+ ENDTEST
+ 
+ void func(void)
+ {
+ 	/*
+ 	 * This is a comment.
+ 	 */
+ }
+ 
+ STARTTEST
  :g/^STARTTEST/.,/^ENDTEST/d
  :1;/start of AUTO/,$wq! test.out
  ENDTEST
*** ../vim-7.3.179/src/testdir/test3.ok	2011-05-10 11:56:26.000000000 +0200
--- src/testdir/test3.ok	2011-05-10 12:05:50.000000000 +0200
***************
*** 1225,1227 ****
--- 1225,1236 ----
  		<< "c";
  }
  
+ 
+ void func(void)
+ {
+ 	/*
+ 	 * This is a comment.
+ 	 */
+ 	foo();
+ }
+ 
*** ../vim-7.3.179/src/version.c	2011-05-10 11:56:26.000000000 +0200
--- src/version.c	2011-05-10 13:37:28.000000000 +0200
***************
*** 716,717 ****
--- 716,719 ----
  {   /* Add new patch number below this line */
+ /**/
+     180,
  /**/

-- 
"Thou shalt not follow the Null Pointer, for at its end Chaos and
Madness lie."

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