xdiff-interface.c: strip newline (and cr) from line before pattern matching
authorBrandon Casey <casey@nrlssc.navy.mil>
Wed, 1 Oct 2008 19:28:26 +0000 (14:28 -0500)
committerJunio C Hamano <gitster@pobox.com>
Thu, 16 Oct 2008 15:31:56 +0000 (08:31 -0700)
POSIX doth sayeth:

"In the regular expression processing described in IEEE Std 1003.1-2001,
the <newline> is regarded as an ordinary character and both a period and
a non-matching list can match one. ... Those utilities (like grep) that
do not allow <newline>s to match are responsible for eliminating any
<newline> from strings before matching against the RE."

Thus far git has not been removing the trailing newline from strings matched
against regular expression patterns. This has the effect that (quoting
Jonathan del Strother) "... a line containing just 'FUNCNAME' (terminated by
a newline) will be matched by the pattern '^(FUNCNAME.$)' but not
'^(FUNCNAME$)'", and more simply not '^FUNCNAME$'.

Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
t/t4018-diff-funcname.sh
xdiff-interface.c
index 40a805a8661d9a8bcd4802c88d33e8106034a452..398bf4b5d8e3d85562563059eaeb7bc8b8e4ce59 100755 (executable)
@@ -69,7 +69,7 @@ test_expect_success 'last regexp must not be negated' '
        grep "fatal: Last expression must not be negated:"
 '
 
-test_expect_failure 'pattern which matches to end of line' '
+test_expect_success 'pattern which matches to end of line' '
        git config diff.java.funcname "Beer$" &&
        git diff --no-index Beer.java Beer-correct.java |
        grep "^@@.*@@ Beer"
index 2c81f40cb657f6e49bc6a7431f830a037713ab38..3bf83f81e38d4a4cc114f3c577241cf7b9eddc7e 100644 (file)
@@ -179,11 +179,21 @@ struct ff_regs {
 static long ff_regexp(const char *line, long len,
                char *buffer, long buffer_size, void *priv)
 {
-       char *line_buffer = xstrndup(line, len); /* make NUL terminated */
+       char *line_buffer;
        struct ff_regs *regs = priv;
        regmatch_t pmatch[2];
        int result = 0, i;
 
+       /* Exclude terminating newline (and cr) from matching */
+       if (len > 0 && line[len-1] == '\n') {
+               if (len > 1 && line[len-2] == '\r')
+                       len -= 2;
+               else
+                       len--;
+       }
+
+       line_buffer = xstrndup(line, len); /* make NUL terminated */
+
        for (i = 0; i < regs->nr; i++) {
                struct ff_reg *reg = regs->array + i;
                if (reg->negate ^ !!regexec(&reg->re,